linq出现InvalidCastException错误

时间:2012-11-27 21:24:35

标签: c# linq

在我的代码下面。它返回异常“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;
        }

    }
}

3 个答案:

答案 0 :(得分: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。区别在于您在第一种情况下再按一个条件过滤序列 - {{1应该是真的。在第二种情况下,这个属性并不重要。所以,你可以添加一个过滤条件而不是item.czyAktywny - 只有当ID等于4时才会验证czyAktywny。你也不需要创建新的您的方法中的(ID != 4 || item.czyAktywny)对象,因为您无论如何都会从通过的列表中返回一个。

答案 1 :(得分:1)

而不是gracz = (Gracz)docelowy;,请使用gracz = docelowy.FirstOrDefault();

答案 2 :(得分:1)

您的select语句返回IEnumerable<Gracz>。因此,当您尝试将其直接投射到Gracz时,计算机不知道如何执行此操作并抛出您所看到的错误。

您可以通过多种方式处理这种情况,但最简单的方法是将FirstOrDefault添加到您的调用中,为您提供

gracz = docelowy.FirstOrDefault();
而不是你现在拥有的。顺便说一下,你还需要将它添加到你的其他if语句中 - 它也有同样的问题。