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

あなたの紛らわしい質問を明確にしましょう。問題は、2 つのローカル変数があり、それぞれが同じ「言いようのない」型 (一連の匿名型) を持っていることです。

特定のコードを次のように変更します。

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

foreach ループで変数を使用するには、if ステートメントのスコープ外で変数を宣言する必要があります。

変数が宣言されているが if ステートメントの外で初期化されていない場合、コンパイラには型を決定する式がないため、暗黙的に型指定することはできません。

foreach ループでのみ使用する場合は、IEnumerable として宣言できます。

于 2012-01-05T23:44:35.623 に答える
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 に答える
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 に答える