2013-10-19 34 views
0

有沒有在C#中的Java界類型變量的Java VS C#

下面的代碼
List<? extends Number> list; 
list = new ArrayList<Float>(); 
list = new ArrayList<Integer>(); 
list.add(Float.valueOf("4.0")); // doesn't compile and it is fine 
Number e = list.get(0); // workds 

我讀到關於協變類型在C#從不管我瞭解所有的接口

List<SomeClass> list2 = new List<SomeClass>(); 
IEnumerable<Object> list3 = list2; // works 

等效/ Java中的類默認支持協方差。根據聲明中使用的類型參數,不支持不遵循協方差的要素(將參數化類型作爲輸入的方法)。意思是,List<? extends Number> 可以參考List<Integer> or a List<Double>,但它不再支持像add()這樣的方法。

現在,在C#的另一端,看起來像我需要找到一個支持協方差的接口,然後使用它。因此,無論何時我想編寫一些泛型類,我都必須編寫一個單獨的接口來支持所有派生類的所有協變操作,並確保我的類實現了該接口?這是正確的還是我錯過了一些東西。

感謝

+1

你是正確的,我認爲這是由於泛型在.Net和Java中實現的方式。如果我理解正確,那麼在JVM字節碼中就沒有泛型,而在.Net中它們會被烘焙到CIL中。每個編譯器的編譯器實現都基於這些事實,因此Java編譯器僅對程序中使用的代碼路徑執行* type erasure *,而C#編譯器必須確保所有用例的完整性。來自真正的專家的一些信息在這裏:http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens。此外,在C#中沒有像基數一樣的東西。 – galenus

回答

1

你的問題,
有沒有在C#中的Java以下代碼等效

List<? extends Number> list; 
    list = new ArrayList<Float>(); 
    list = new ArrayList<Integer>(); 
    list.add(Float.valueOf("4.0")); // doesn't compile and it is fine 
    Number e = list.get(0); // workds 

沒有,直接就沒有等價,因爲沒有基地或超類或接口'Number',但是有一個Equivalent(對'?'運算符的種類),where關鍵字。

您可以通過msdn page瞭解關於它的更多信息。

你可以在課堂上做這個內嵌的變量簡稱爲:

public class ArrayList<T> where T: someBaseClass 
{ 
    List<T> list = new List<DerivedTypeOfSomeBaseClass>(); 
} 

或功能

public T getArrayList<T>(ArrayList<T> arr) where T: someBaseClass 
List<T> list = new List<DerivedTypeOfSomeBaseClass>() 

你的問題裏面現在

,在另一側C#,看起來像我需要找到一個支持協變的接口,然後使用它。因此,無論何時我想編寫一些泛型類,我都必須編寫一個單獨的接口來支持所有派生類的所有協變操作,並確保我的類實現了該接口?這是正確的還是我失去了一些東西

協變和逆變狀態的一般概念,協方差是使用多個派生型比泛型參數指定的能力,而逆變就是用較少的能力派生類型。
有關協方差和反變量的詳細說明,您可以閱讀MSDN link
所以,你是對的,如果你想通過通用的方式來做這件事,你必須有一個共同的基礎接口,支持所有的協變操作。

在您的具體情況對數字的所有字節,雙,浮法,整數,長,在C#中短期實現了IComparable,IFormattable,IConvertible,IComparable的,IEquatable接口,所以對於第一個問題,

public class Program<K> where K : IComparable, IFormattable, IConvertible, IComparable<K>, IEquatable<K> 
{ 
    static void Main() 
    { 
     Program<int> pro = new Program<int>(); 
     Program<Byte> bpro = new Program<Byte>(); 
     Program<Double> dpro = new Program<Double>(); 
     Program<Int64> fpro = new Program<Int64>(); 
     Program<long> lpro = new Program<long>(); 
     Program<short> spro = new Program<short>(); 
    }