2013-03-22 93 views
13

比方說,我有一個通用類,如下所示:通配符相當於在C#泛型

public class GeneralPropertyMap<T> 
{ 
} 

在一些其他類我有需要在GeneralPropertyMap<T>陣列的方法。在Java中,以便採取在包含任何類型的GeneralPropertyMap的方法是這樣的一個數組:

private void TakeGeneralPropertyMap(GeneralPropertyMap<?>[] maps) 
{ 
} 

我們使用通配符,這樣以後我們可以稱之爲TakeGeneralPropertyMap路過一堆GeneralPropertyMap與任何類型T每個,像這樣:

GeneralPropertyMap<?>[] maps = new GeneralPropertyMap<?>[3]; 
maps[0] = new GeneralPropertyMap<String>(); 
maps[1] = new GeneralPropertyMap<Integer>(); 
maps[2] = new GeneralPropertyMap<Double>(); 
//And finally pass the array in. 
TakeGeneralPropertyMap(maps); 

我試圖找出在C#中的等價物,但沒有成功。有任何想法嗎?

+0

您是否嘗試過製作功能拍攝'GeneralPropertyMap [] maps' ..我想這應該是因爲協方差 – Ankur 2013-03-22 16:22:36

回答

3

沒有直接等同於在C#。

在C#中,這往往會被具有您的泛型類實現非泛型接口或基類來完成:

interface IPropertyMap 
{ 
    // Shared properties 
} 

public class GeneralPropertyMap<T> : IPropertyMap 
{ 
} 

然後,您可以通過這些數組:

IPropertyMap[] maps = new IPropertyMap[3]; 
// ... 

TakePropertyMap(maps); 
+0

@EricJ的工作。誤解了這個問題......修正了 – 2013-03-22 16:17:50

+0

我瞭解通用方法,但在這種情況下他們不會這樣做。每次我調用它時,我只能爲GeneralPropertyMap指定一種類型。所以我只能稱它爲傳遞一個GeneralPropertyMap的數組[]或GeneralPropertyMap ,等等。 – AxiomaticNexus 2013-03-22 16:19:02

15

C#中的泛型比Java中的泛型有更強的保證。因此,你在C#中想要的東西,你必須讓從非通用版本的類(或接口)的GeneralPropertyMap<T>類繼承。現在

public class GeneralPropertyMap<T> : GeneralPropertyMap 
{ 
} 

public class GeneralPropertyMap 
{ 
    // Only you can implement it: 
    internal GeneralPropertyMap() { } 
} 

你可以這樣做:

private void TakeGeneralPropertyMap(GeneralPropertyMap[] maps) 
{ 
} 

和:

GeneralPropertyMap[] maps = new GeneralPropertyMap[3]; 
maps[0] = new GeneralPropertyMap<String>(); 
maps[1] = new GeneralPropertyMap<Integer>(); 
maps[2] = new GeneralPropertyMap<Double>(); 
TakeGeneralPropertyMap(maps); 
+1

它仍然不夠好,因爲在界面中你很可能想要一個方法返回或從「TakeGeneralPropertyMap」方法中使用通配符,這是你不能做的,因爲我們不希望接口是通用類型。但是,這個答案至少會接近。謝謝 :-) – AxiomaticNexus 2013-04-24 14:57:16

0

請從GeneralPropertyMapIGeneralPropertyMap)成員的接口,然後採取IGeneralPropertyMap[]作爲參數。

8

雖然,正如其他人所指出的,在C#沒有確切的對應關係通配符,他們的一些使用情況可以用covariance/contravariance覆蓋。

public interface IGeneralPropertyMap<out T> {} // a class can't be covariant, so 
             // we need to introduce an interface... 

public class GeneralPropertyMap<T> : IGeneralPropertyMap<T> {} // .. and have our class 
                  // inherit from it 

//now our method becomes something like 
private void TakeGeneralPropertyMap<T>(IList<IGeneralPropertyMap<T>> maps){} 

// and you can do 
    var maps = new List<IGeneralPropertyMap<Object>> { 
     new GeneralPropertyMap<String>(), 
     new GeneralPropertyMap<Regex>() 
    }; 
    //And finally pass the array in. 
    TakeGeneralPropertyMap<Object>(maps); 

需要注意的是,你不能使用協方差值類型,所以添加新GeneralPropertyMap<int>()我們的列表失敗在編譯時。

cannot convert from 'GeneralPropertyMap<int>' to 'IGeneralPropertyMap<object>' 

這種方法可能比有你的類/接口的情況下,要約束的是GeneralPropertyMap可以包含各類非通用版本更方便。在這種情況下:

public interface IMyType {} 
public class A : IMyType {} 
public class B : IMyType {} 
public class C : IMyType {} 

public interface IGeneralPropertyMap<out T> where T : IMyType {} 

可以讓你有:

var maps = new List<IGeneralPropertyMap<IMyType>> { 
    new GeneralPropertyMap<A>(), 
    new GeneralPropertyMap<B>() , 
    new GeneralPropertyMap<C>() 
}; 
TakeGeneralPropertyMap(maps);