当我的类多次实现IEnumerable <t>时,为什么我不能使用LINQ to Objects?</t>

时间:2011-06-24 19:09:53

标签: c# ienumerable linq-to-objects

我有一个有趣的问题,一个类继承自实现IEnumerable的类,但我也希望该类为不同的类型实现IEnumerable。除了IEnumerable扩展方法之外,一切都有效,这意味着默认情况下我不能对对象执行任何LINQ,而不必先进行强制转换。除了不断演员之外,有没有人有任何想法?

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqTesting
{
    public class Trucks<T> : Vehicles, IEnumerable<Truck>
    {    
        public Trucks()
        {    
            // Does Compile
            var a = ((IEnumerable<Truck>)this).FirstOrDefault();
            // Doesn't Compile, Linq.FirstOrDefault not found
            var b = this.FirstOrDefault();
        }    

        public new IEnumerator<Truck> GetEnumerator() { throw new NotImplementedException(); }
    }    

    public class Vehicles : IEnumerable<Vehicle>
    {    
        public IEnumerator<Vehicle> GetEnumerator() { throw new NotImplementedException(); }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
    }    

    public class Vehicle { }

    public class Truck : Vehicle { }
}     

5 个答案:

答案 0 :(得分:7)

将您的代码更改为:

public class Trucks : Vehicles<Truck>
{    
}    

public class Vehicles<T> : IEnumerable<T>
    where T : Vehicle
{    
}    

public class Vehicle { }

public class Truck : Vehicle { }

答案 1 :(得分:7)

实际上你可以,但你不能利用泛型类型推断,因为你的类实现了两个不同类型的两个IEnumerable<T>,编译器无法知道你想要使用哪种类型。

您可以指定它直接,例如:

var b = this.FirstOrDefault<Truck>();

答案 2 :(得分:4)

实现IEnumerable多次混淆编译器,IEnumerable&lt;&gt;它应该考虑到这一点。

IEnumerable<Vehicle> or IEnumerable<Truck>?

this.FirstOrDefault<Truck>() might compile. 

答案 3 :(得分:2)

看起来你有点卡住了。这是一个减少打字的建议。您可以为一些常用的IEnumerable&lt;&gt;创建扩展方法。类型。

var a = myList.AsTruckEnumerable().FirstOrDefault();

public static partial class Extensions
{
  public static IEnumerable<Truck> AsTruckEnumerable (this IEnumerable<Truck> trucks)
  {
     return trucks;
  }
}

public class Trucks<T> : Vehicles, IEnumerable<Truck>
{    
   public Trucks()
   {    
      // Does Compile
      var a = ((IEnumerable<Truck>)this).FirstOrDefault();

      // Does compile
      var b = this.AsTruckEnumerable().FirstOrDefault();
      // Doesn't Compile, Linq.FirstOrDefault not found
      //var b = this.FirstOrDefault();
   }    

   public new IEnumerator<Truck> GetEnumerator() { throw new NotImplementedException(); } 
}    

答案 4 :(得分:0)

  

public new IEnumerator GetEnumerator()

该行中的new个关键字隐藏从Vehicle类继承的GetEnumerator()方法。我不确定这会有效,但也许会尝试explicit interface implementation