在条件范围内声明隐式类型变量并在外部使用它

在下面的简化代码中,

if(city == "New York City") { var MyObject = from x in MyEFTable where x.CostOfLiving == "VERY HIGH" select x.*; } else { var MyObject = from x in MyEFTable where x.CostOfLiving == "MODERATE" select x.*; } foreach (var item in MyObject) { Console.WriteLine(""); } 

在条件块之外无法访问变量MyObject。 我怎样才能在if..else之外迭代?

让我们澄清一下令人困惑的问题。 问题是你有两个局部变量,每个变量都有相同的“unspeakable”类型 – 一个匿名类型的序列。

我会改变你的具体代码:

 string cost = city == "NYC" ? "HIGH" : "MODERATE"; var query = from row in table where row.Cost == cost select new { row.Population, row.Elevation }; 

但是,如果由于某种原因仍然需要维护代码的结构,可以这样做:

 static IEnumerable SequenceByExample(T t){ return null; } ... var query = SequenceByExample(new { Population = 0, Elevation = 0.0 } ); if (whatever) query = ... else query = ... 

这是一个名为“按示例执行”的技巧的变体,其中您将一个匿名类型的示例提供给generics方法。 然后,方法类型推断会确定返回类型是什么,并将其用作隐式类型本地的类型。 在运行时,它只会创建一个无用的对象,然后快速丢弃。

如果你使用的是命名类型,只需在if之前声明一个具有该类型的变量,但问题就是微不足道的。

所以我假设您选择了一个匿名类型,因此您无法使用该类型显式声明变量。

通过示例演员可以在这里工作。 但这并不是一个好的解决方案。 可能创建命名类型是一个更好的主意。

 var myObject =Enumerable.Empty.Select(row=>select new {columnA, columnB, columnC}); if(city == "New York City") { myObject= from x in MyEFTable where x.CostOfLiving == "VERY HIGH" select select new {columnA, columnB, columnC}; } else { myObject = from x in MyEFTable where x.CostOfLiving == "MODERATE" select select new {columnA, columnB, columnC}; } 

或者在您的具体示例中,只能在条件之后进行投影:

 IQueryable partialQuery; if(city == "New York City") partialQuery=MyEFTable.Where(x=>xxCostOfLiving == "VERY HIGH"); else partialQuery=MyEFTable.Where(x=>xxCostOfLiving == "MODERATE"); var myObject=partialQuery.Select(x=>x.new {columnA, columnB, columnC}); 

要么:

 Expression> filter;//Note that this is an Expression, not just a delegate if(city == "New York City") filter=x=>xxCostOfLiving == "VERY HIGH"; else filter=x=>xxCostOfLiving == "MODERATE"; var myObject=MyEFTable.Where(filter).Select(x=>x.new {columnA, columnB, columnC}); 

甚至只是:

 string s; if(city == "New York City") s="VERY HIGH"; else s="MODERATE"; var myObject=MyEFTable.Where(x=>x.CostOfLiving == s).Select(x=>x.new {columnA, columnB, columnC}); 

哪一个合适取决于您如何简化您的问题。

试试这个:

 var ret = default(object); 

试试这个:

 System.Linq.IQueryable MyObject = null; if(city == "New York City") { MyObject = from x in MyEFTable where x.CostOfLiving == "VERY HIGH" select x.*; } else { MyObject = from x in MyEFTable where x.CostOfLiving == "MODERATE" select x.*; } foreach (var item in MyObject) { Console.WriteLine(""); } 

您需要在if语句的范围之外声明变量,以便在foreach循环中使用它。

如果声明变量但未在if语句之外初始化,则无法隐式输入,因为编译器将没有表达式来确定类型。

如果它只在foreach循环中使用,你可以将它声明为IEnumerable。

 List list = null; if(city == "New York City") list = (from x in MyEFTable where x.CostOfLiving == "VERY HIGH" select x.*).ToList(); else list = (from x in MyEFTable where x.CostOfLiving == "MODERATE" select x.*).ToList(); foreach (var item in list) Console.WriteLine(""); 

你必须在条件之前将MyObject定义为var:

 var MyObject = from x in MyEFTable where x.CostOfLiving == "SOMETHING THAT'LL RETURN NO ROWS" select x.*; 

这将为MyObject变量分配一个模式。

现在你可以继续你的条件:

 if(city == "New York City") { MyObject = from x in MyEFTable where x.CostOfLiving == "VERY HIGH" select x.*; } else { MyObject = from x in MyEFTable where x.CostOfLiving == "MODERATE" select x.*; }