2013-03-22 91 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);