0

私のコードの下。例外「InvalidCastException」を返します。そして主な質問は-なぜですか?
なにが問題ですか?

エラーテキスト:

タイプ'WhereSelectListIterator`2[Monopolowy_beta.Gracz、Monopolowy_beta.Gracz]'のオブジェクトをタイプ'Monopolowy_beta.Gracz'にキャストできません。

namespace Monopolowy_beta
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Gracz> lista = new List<Gracz> { };
            Gracz g1 = new Gracz();
            Gracz g2 = new Gracz();
            Gracz g3 = new Gracz();
            g2.Id = 3;

            lista.Add(g1);
            lista.Add(g2);
            lista.Add(g3);

            g1 = GraczeTools.UstawAktywnegoGracza(lista, 3);


            Console.ReadKey();
        }
    }
}

これらの行のエラー:
var docelowy = from item in listagraczy where (item.Id==ID && item.czyAktywny == true) select listagraczy[listagraczy.IndexOf(item) + 1]; gracz = (Gracz)docelowy;

namespace Monopolowy_beta
{
    static class GraczeTools
    {

        public static Gracz UstawAktywnegoGracza(List<Gracz> listagraczy, int ID)
        { 
            Gracz gracz = new Gracz();
            if (ID == 4){
                var docelowy = from item in listagraczy where (item.czyAktywny == true && item.Id == 3) select listagraczy[1];
                gracz = (Gracz)docelowy;
            }

            if (ID != 4){
                var docelowy = from item in listagraczy where (item.Id==ID && item.czyAktywny == true) select listagraczy[listagraczy.IndexOf(item) + 1];
                gracz = (Gracz)docelowy;
            }


            return gracz;
        }

    }
}
4

3 に答える 3

3
var docelowy = from item in listagraczy 
               where (item.czyAktywny == true && item.Id == 3) 
               select listagraczy[1];

このクエリを調べてみましょう。条件を満たすすべてのアイテムを検索し(はい、単一のアイテムではなくシーケンスを返します)、そのようなアイテムごとに、listagraczyリストの2番目の要素を返します。はい、あなたの状態に合ったアイテムはありません。

デフォルトではクエリが結果を返すため、item代わりに(これはクエリの範囲変数)を選択して結果に適用する必要があると思います。FirstOrDefaultIEnumerable<Gracz>

var docelowy = (from item in listagraczy 
                where (item.czyAktywny == true && item.Id == 3) 
                select item).FirstOrDefault();

流暢なAPIで書く方が良いです:

var docelowy = listagraczy.FirstOrDefault(item => item.czyAktywny && item.Id == 3);

item.czyAktywnyまた、条件で直接(つまり、の代わりに)ブール値を使用できますitem.czyAktywny == true


少しリファクタリングすると、メソッドは次のようになります。

public static Gracz UstawAktywnegoGracza(List<Gracz> listagraczy, int ID)
{ 
   return listagraczy
           .FirstOrDefault(item => item.Id == 3 && (ID != 4 || item.czyAktywny));
}

使い方:

if (ID == 4)メソッドに2つの条件付きブロックがありますif (ID != 4)(実際にはそうif ... elseです。違いは、最初のケースではもう1つの条件でシーケンスをフィルタリングしていることです-trueである必要がitem.czyAktywnyあります。2番目のケースではこのプロパティは重要ではありません。したがって、1つのフィルタリング条件を追加できます代わりに(ID != 4 || item.czyAktywny)、-czyAktywnyは、IDが4の場合にのみ検証されます。またGracz、渡されたリストからオブジェクトを返すため、メソッドに新しいオブジェクトを作成する必要はありません。

于 2012-11-27T21:30:48.970 に答える
1

の代わりにgracz = (Gracz)docelowy;gracz = docelowy.FirstOrDefault();

于 2012-11-27T21:30:00.463 に答える
1

selectステートメントはを返していIEnumerable<Gracz>ます。したがって、それをGracz直接キャストしようとすると、コンピューターはそれを行う方法を知らず、表示されているエラーをスローします。

この状況を処理する方法はいくつかありますが、最も簡単な方法はFirstOrDefault、呼び出しに追加するだけで、

gracz = docelowy.FirstOrDefault();

あなたが現在持っているものの代わりに。ちなみに、これを他のifステートメントにも追加する必要があります-同じ問題があります。

于 2012-11-27T21:36:16.867 に答える