Axi*_*xus 18 .net c# arrays generics wildcard
假设我有一个泛型类,如下所示:
public class GeneralPropertyMap<T>
{
}
Run Code Online (Sandbox Code Playgroud)
在其他一些类中,我有一个接收数组的方法GeneralPropertyMap<T>.在Java中,为了获取包含任何类型GeneralPropertyMap的方法的数组,将如下所示:
private void TakeGeneralPropertyMap(GeneralPropertyMap<?>[] maps)
{
}
Run Code Online (Sandbox Code Playgroud)
我们使用通配符,以便稍后我们可以调用每个类型的任意类型的TakeGeneralPropertyMap传递,如下所示:GeneralPropertyMapT
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);
Run Code Online (Sandbox Code Playgroud)
我试图弄清楚C#中的等价物并没有成功.有任何想法吗?
Dan*_*ker 18
C#中的泛型比Java中的泛型更有力.因此,要在C#中执行您想要的操作,您必须让GeneralPropertyMap<T>该类继承自该类(或接口)的非泛型版本.
public class GeneralPropertyMap<T> : GeneralPropertyMap
{
}
public class GeneralPropertyMap
{
// Only you can implement it:
internal GeneralPropertyMap() { }
}
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
private void TakeGeneralPropertyMap(GeneralPropertyMap[] maps)
{
}
Run Code Online (Sandbox Code Playgroud)
和:
GeneralPropertyMap[] maps = new GeneralPropertyMap[3];
maps[0] = new GeneralPropertyMap<String>();
maps[1] = new GeneralPropertyMap<Integer>();
maps[2] = new GeneralPropertyMap<Double>();
TakeGeneralPropertyMap(maps);
Run Code Online (Sandbox Code Playgroud)
虽然正如其他人所指出的那样,在c#中与通配符没有确切的对应关系,但是他们的一些用例可以用协方差/逆变来覆盖.
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);
Run Code Online (Sandbox Code Playgroud)
需要注意的是,您不能对值类型使用协方差,因此GeneralPropertyMap<int>()在编译时添加新列表会失败.
cannot convert from 'GeneralPropertyMap<int>' to 'IGeneralPropertyMap<object>'
Run Code Online (Sandbox Code Playgroud)
如果要约束GeneralPropertyMap可包含的类型,则此方法可能比具有非通用版本的类/接口更方便.在这种情况下:
public interface IMyType {}
public class A : IMyType {}
public class B : IMyType {}
public class C : IMyType {}
public interface IGeneralPropertyMap<out T> where T : IMyType {}
Run Code Online (Sandbox Code Playgroud)
允许你拥有:
var maps = new List<IGeneralPropertyMap<IMyType>> {
new GeneralPropertyMap<A>(),
new GeneralPropertyMap<B>() ,
new GeneralPropertyMap<C>()
};
TakeGeneralPropertyMap(maps);
Run Code Online (Sandbox Code Playgroud)
在 C# 中没有直接的等价物。
在 C# 中,这通常是通过让泛型类实现非泛型接口或基类来完成的:
interface IPropertyMap
{
// Shared properties
}
public class GeneralPropertyMap<T> : IPropertyMap
{
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以传递以下数组:
IPropertyMap[] maps = new IPropertyMap[3];
// ...
TakePropertyMap(maps);
Run Code Online (Sandbox Code Playgroud)