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列表的第二个元素。是的,您没有符合您条件的物品。

我认为您应该选择item(这是您查询的范围变量),并应用于FirstOrDefault结果,因为默认情况下查询将返回IEnumerable<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)并且if (ID != 4)(实际上是if ... else。不同之处在于,您在第一种情况下通过一个条件过滤序列 -item.czyAktywny应该为真。在第二种情况下,此属性无关紧要。因此,您可以添加一个过滤条件相反(ID != 4 || item.czyAktywny)- 只有当 ID 等于 4 时才会验证 czyAktywny。此外,您不需要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 回答