必须初始化隐式类型的局部变量

时间:2015-09-21 08:58:01

标签: c# asp.net-mvc linq

我想动态地设置这样的条件: -

var data;
if(employeId != 0) {
 data = (from a in ctx.tblTO1
             join b in ctx.tblTO2
                    on a.Company equals b.Company
                    where a.Id == b.Id &&
                    a.employeeId == employeeId
                    select new { a = a, b = b }).ToList();
}else{
     data = (from a in ctx.tblTO1
                 join b in ctx.tblTO2
                        on a.Company equals b.Company
                        where a.Id == b.Id &&
                        a.Cat == cats
                        select new { a = a, b = b }).ToList();
}

上述表达式的结果是匿名类型。所以我无法宣布它&第一行给出错误。 Implicitly typed local variables must be initialised

解决这个问题的方法是什么?我们可以使用单独的函数,但那么函数返回类型是什么?

7 个答案:

答案 0 :(得分:5)

嗯,当然var data;毫无意义。

您可以使用适当的字段定义类型作为元素类型。如果同一类型出现不止一次,这将特别有用。

您也可以使用?: if…else来使用var data = (employeeId != 0) ? (from a in ctx.tblTO1 join b in ctx.tblTO2 on a.Company equals b.Company where a.Id == b.Id && a.employeeId == employeeId select new { a = a, b = b }).ToList() : (from a in ctx.tblTO1 join b in ctx.tblTO2 on a.Company equals b.Company where a.Id == b.Id && a.Cat == cats select new { a = a, b = b }).ToList();

var query = from a in ctx.tblTO1
            join b in ctx.tblTO2
            on a.Company equals b.Company
            where a.Id == b.Id
            select new { a = a, b = b };

if (employeeId != 0)
  query = query.Where(i => i.a.employeeId == employeeId);
else
   query = query.Where(i => i.a.Cat == cats);
var data = query.ToList();

但也许最明显的是修改一个查询,以确定每种情况的不同之处:

ToList()

这样做的好处是可以在代码中使两种情况之间的区别更加清晰。如果您以不再需要的方式更改代码,那么将novalidate分开也有一个更明显的优势。

答案 1 :(得分:3)

您可以使用DTO类而不是匿名类型。 Resharper可以为您进行转型。或者,您可以使用条件运算符来允许类型推断在此处起作用:

var data = employeId != 0 ? (query1) : (query2);

这不会很漂亮。

还有另一个黑客:

var data = new [] { new { a = 0, b = 0 } }.ToList();

这将创建一个虚拟对象以使var类型推断工作。你可能不应该这样做......

答案 2 :(得分:0)

SELECT TOP 1 t.[Business Email Address] FROM dbo.FRA$ t WHERE [HR Manager ID] = t.[Emplid]

答案 3 :(得分:0)

您可以按如下方式重写查询

(from a in ctx.tblTO1
         join b in ctx.tblTO2
                on a.Company equals b.Company
                where a.Id == b.Id &&
                ( (employeId != 0 && a.employeeId == employeeId) || (a.Cat == cats))
                select new { a = a, b = b }).ToList();

答案 4 :(得分:0)

var data;无法正常工作,因为var只针对初始化者进行解决,而不是任何后续作业。

您有两个主要选择:要么您可以停止使用匿名类型,要么确保您拥有初始化程序。第一个看起来像:

class MyClass {
    public T01 a;
    public T02 b;
}

现在,您可以使用List<MyClass>

其中第二个可以分为两个子选项:您可以重新处理现有逻辑以适合单个表达式,也可以使用虚拟值进行初始化。

其中第一个看起来像var data = condition ? query1 : query2;

其中第二个看起来像var data = true ? null : query1;,其中query1实际上从未被评估过,它仅用于确定data的类型。

答案 5 :(得分:0)

您不仅可以隐含地声明变量,而且不会给它任何值。 当你写:

{{validationScope}}

这意味着,您有一个var a = "foo"; 类型的变量,而不仅仅是一个给出string值的变量。编译器需要知道类型的确切类型,即使类型是从使用中隐含的。

当您只编写声明string时,编译器不知道如何处理它。它是var a吗?也许object?一个号码?堆栈上要分配多少内存?

如果声明变量,则使用静态类型语言string,声明类型。 你可以这样做:

C#

答案 6 :(得分:0)

您可以使用var关键字代替dynamic关键字。您可以在以下官方MSDN网站上找到更多信息:

Dynamic Type C#

页面上的一些摘录:

  

Visual C#2010引入了一种新的动态类型。类型是静态的   类型,但动态类型的对象绕过静态类型检查。在   大多数情况下,它的功能就像它有类型对象。在编译时,一个   假定键入动态的元素支持任何操作。

这是var关键字的替代方案。但是我认为你可以在没有动态的情况下将where子句中的条件作为本页提到的其他答案。

 .Where(a=> (a.EmployeeId != 0 && a.EmployeeId == employeeId) || your other conditions)