繁体   English   中英

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

[英]Why can't I use LINQ to Objects when my class implements IEnumerable<T> multiple times?

我有一个有趣的问题,其中一个类从实现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 { }
}     

将您的代码更改为:

public class Trucks : Vehicles<Truck>
{    
}    

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

public class Vehicle { }

public class Truck : Vehicle { }

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

您可以将其指定为直接,例如:

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

实现IEnumerable多次调用会使编译器感到困惑,为此应该考虑使用IEnumerable <>。

IEnumerable<Vehicle> or IEnumerable<Truck>?

this.FirstOrDefault<Truck>() might compile. 

看起来您有点卡住了。 这是减少打字的建议。 您可以为某些常用的IEnumerable <>类型创建扩展方法。

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(); } 
}    

公开新的IEnumerator GetEnumerator()

该行中的new关键字隐藏了从Vehicle类继承的GetEnumerator()方法。 我不确定这是否可行,但是也许尝试使用显式接口实现

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM