C#generics中的通配符等价物
假设我有一个generics类,如下所示:
public class GeneralPropertyMap { }
在其他一些类中,我有一个方法,它接受一个GeneralPropertyMap
数组。 在Java中,为了获取包含任何类型的GeneralPropertyMap
的数组,该方法将如下所示:
private void TakeGeneralPropertyMap(GeneralPropertyMap[] maps) { }
我们使用通配符,以便稍后我们可以调用TakeGeneralPropertyMap
传递一堆具有T
任何类型的GeneralPropertyMap
,如下所示:
GeneralPropertyMap[] maps = new GeneralPropertyMap[3]; maps[0] = new GeneralPropertyMap(); maps[1] = new GeneralPropertyMap(); maps[2] = new GeneralPropertyMap(); //And finally pass the array in. TakeGeneralPropertyMap(maps);
我试图在C#中找出一个没有成功的等价物。 有任何想法吗?
C#中的generics比Java中的generics更有力。 因此,要在C#中执行所需操作,必须让GeneralPropertyMap
类inheritance该类(或接口)的非generics版本。
public class GeneralPropertyMap : 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(); maps[1] = new GeneralPropertyMap(); maps[2] = new GeneralPropertyMap(); TakeGeneralPropertyMap(maps);
虽然正如其他人所指出的那样,在c#中与通配符没有确切的对应关系,但是他们的一些用例可以用协方差/逆变来覆盖。
public interface IGeneralPropertyMap {} // a class can't be covariant, so // we need to introduce an interface... public class GeneralPropertyMap : IGeneralPropertyMap {} // .. and have our class // inherit from it //now our method becomes something like private void TakeGeneralPropertyMap (IList> maps){} // and you can do var maps = new List> { new GeneralPropertyMap(), new GeneralPropertyMap() }; //And finally pass the array in. TakeGeneralPropertyMap
需要注意的是,您不能对值类型使用协方差,因此在编译时将新的GeneralPropertyMap
到列表中会失败。
cannot convert from 'GeneralPropertyMap' to 'IGeneralPropertyMap
如果要约束GeneralPropertyMap
可以包含的类型,则此方法可能比具有非generics版本的类/接口更方便。 在这种情况下:
public interface IMyType {} public class A : IMyType {} public class B : IMyType {} public class C : IMyType {} public interface IGeneralPropertyMap where T : IMyType {}
允许你拥有:
var maps = new List> { new GeneralPropertyMap(), new GeneralPropertyMap() , new GeneralPropertyMap() }; TakeGeneralPropertyMap(maps);
在C#中没有与此直接等价的东西。
在C#中,通常可以通过让generics类实现非generics接口或基类来完成:
interface IPropertyMap { // Shared properties } public class GeneralPropertyMap : IPropertyMap { }
然后你可以传递这些数组:
IPropertyMap[] maps = new IPropertyMap[3]; // ... TakePropertyMap(maps);
从GeneralPropertyMap
( IGeneralPropertyMap
)的成员创建一个接口,然后将IGeneralPropertyMap[]
作为参数。