在下面的简化代码中,
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("<item's details>");
}
在条件块之外无法访问变量MyObject。我怎样才能在if..else外面迭代?
答案 0 :(得分:24)
让我们澄清一下令人困惑的问题。问题是你有两个局部变量,每个变量都有相同的“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<T> SequenceByExample<T>(T t){ return null; }
...
var query = SequenceByExample(new { Population = 0, Elevation = 0.0 } );
if (whatever)
query = ...
else
query = ...
这是一个名为“按示例执行”的技巧的变体,其中您将一个匿名类型的示例提供给泛型方法。然后,方法类型推断确定返回类型是什么,并将其用作隐式类型本地的类型。在运行时,它只会创建一个无用的对象,然后快速丢弃。
答案 1 :(得分:4)
如果您使用的是命名类型,只需在if
之前声明一个具有该类型的变量,但这个问题将是微不足道的。
所以我假设您选择了一个匿名类型,因此您无法使用该类型显式声明变量。
通过示例演员可以在这里工作。但这并不是一个好的解决方案。可能创建一个命名类型是一个更好的主意。
var myObject =Enumerable.Empty<RowType>.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<RowType> partialQuery;
if(city == "New York City")
partialQuery=MyEFTable.Where(x=>x.x.CostOfLiving == "VERY HIGH");
else
partialQuery=MyEFTable.Where(x=>x.x.CostOfLiving == "MODERATE");
var myObject=partialQuery.Select(x=>x.new {columnA, columnB, columnC});
或者:
Expression<Predicate<RowType>> filter;//Note that this is an Expression, not just a delegate
if(city == "New York City")
filter=x=>x.x.CostOfLiving == "VERY HIGH";
else
filter=x=>x.x.CostOfLiving == "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});
哪一个合适取决于您如何简化问题。
答案 2 :(得分:3)
试试这个:
var ret = default(object);
答案 3 :(得分:2)
试试这个:
System.Linq.IQueryable<MyEFTable Object type> 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("<item's details>");
}
答案 4 :(得分:1)
List<MyObject> 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("<item's details>");
答案 5 :(得分:1)
您需要在if语句的范围之外声明变量,以便在foreach循环中使用它。
如果声明变量但未在if语句之外初始化,则无法隐式输入,因为编译器没有表达式来确定类型。
如果它只在foreach循环中使用,你可以将它声明为IEnumerable。
答案 6 :(得分:0)
你必须在条件之前将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.*;
}