5

在下面的简化代码中,

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 之外进行迭代?

4

7 回答 7

24

让我们澄清你令人困惑的问题。问题是您有两个局部变量,每个变量都具有相同的“不可描述”类型——一系列匿名类型。

我会像这样更改您的特定代码:

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 = ...

这是一种称为“通过示例强制转换”的技巧的变体,在该技巧中,您将匿名类型的示例提供给泛型方法。方法类型推断然后确定返回类型是什么,并将其用作隐式类型本地的类型。在运行时,它只会创建一个无用的对象,然后很快就会被丢弃。

于 2012-01-06T00:10:05.690 回答
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});

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

于 2012-01-05T23:41:17.210 回答
3

试试这个:

var ret = default(object);
于 2013-11-19T11:44:48.760 回答
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>");
}
于 2012-11-14T12:32:27.173 回答
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>");    
于 2012-01-05T23:40:35.447 回答
1

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

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

如果它只用于 foreach 循环,您可以将其声明为 IEnumerable。

于 2012-01-05T23:44:35.623 回答
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.*;

}
于 2012-01-05T23:40:15.230 回答