2011-06-24 53 views
7

我有一個有趣的問題,其中一個類從實現IEnumerable的類繼承,但我也希望該類爲不同類型實現IEnumerable。除IEnumerable擴展方法之外,一切都可以使用,這意味着默認情況下我不能對LINQ進行任何操作,而無需先執行任何操作。除了不斷鑄造,有沒有人有任何想法?當我的類多次實現IEnumerable <T>時,爲什麼我不能使用LINQ to Objects?

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 { } 
}  
+2

是不是你的Truck對象繼承兩個IEnumerable類型?您如何期望編譯器找出您想要使用的枚舉類型,嘗試向上轉換爲您想要的類型,然後選擇FirstOrDefault –

回答

6

其實你可以,但你不能把泛型類型推斷的優勢,因爲你的類實現兩種不同類型的兩個IEnumerable<T>和編譯器無法知道您想使用哪種類型。

您可以指定照片直接它,像:

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

這真的是我想念的。這很混亂,因爲intellisense會彈出顯示方法,但它也會在同一行中顯示錯誤,因爲編譯器不能再利用泛型類型推斷。 – Daryl

4

實現IEnumerable的多個時間混淆編譯器,它的IEnumerable <>應該考慮這一點。

IEnumerable<Vehicle> or IEnumerable<Truck>? 

this.FirstOrDefault<Truck>() might compile. 
0

公共新的IEnumerator的GetEnumerator()

即在該行獸皮new關鍵字從車輛類繼承的的GetEnumerator()方法。我不確定這會起作用,但也許嘗試explicit interface implementation

+0

對某些接口使用顯式接口實現並對其他接口隱式不會改變擴展方法解析。它只會幫助你直接調用'GetEnumerator()',所以這沒有幫助。 – binki

7

你的代碼更改爲:

public class Trucks : Vehicles<Truck> 
{  
}  

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

public class Vehicle { } 

public class Truck : Vehicle { } 
+0

只需要幾分鐘,以減緩;) – Clayton

+0

@Clayton - 那就是生活;-) –

+0

不幸的是我沒有訪問基類代碼,但這將是正確的解決方案。我將不得不看看我能否做出改變。謝謝! – Daryl

2

看起來你有點卡住。這裏有一個建議,以減少你的打字。您可以爲一些常用的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(); } 
}  
相關問題