[英]Type parameters, constraints and covariance/contravariance
Let's say I have the following classes that have different implementations based on the object to be stored in: 假设我有以下类,这些类根据要存储的对象具有不同的实现:
public class ListOfPersistent<T> :
IList<T> where T : Persistent {... implementation ...}
public class ListOfNonPersistent<T> :
IList<T> {... implementation ...}
And I want to use one of another version on the above classes by doing something like this: 我想通过做这样的事情在上述类中使用另一个版本:
public class PersistentList<T> : IList<T> {
protected PersistentList() {
if (list != null) {
return;
}
if (Extensions.IsPersistent<T>()) {
list = new ListOfPersistent<T>();
} else {
list = new ListOfNonPersistent<T>();
}
}
protected IList<T> list;
....
}
Of course the above does not compiles, because there is a type constrain on the first class and none on the second. 当然,以上内容不会编译,因为在第一类上没有类型约束,在第二类上没有类型约束。 Is there any way I can: Tell the compiler that it should not check the constrain on this specific case (
list = new ListOfPersistent<T>()
) because I KNOW it will be of that type, or do some covariance/contravariance magic so the code compiles without any issues? 有什么办法可以告诉我:告诉编译器它不应该检查这种特定情况下的约束(
list = new ListOfPersistent<T>()
),因为我知道它将是这种类型,或者做一些协方差/协方差魔术,所以代码编译没有任何问题?
Covariance and contravariance won't help you here because IList<T>
is invariant. 因为
IList<T>
是不变的,所以协方差和协变对您无济于事。
Personally I would argue that you have a flaw in your class design. 我个人认为您的班级设计有缺陷。 You shouldn't want to instantiate a
ListOfPersistent<T>
and then place it in a variable whose type, IList<T>
, is incompatible. 您不希望实例化
ListOfPersistent<T>
,然后将其放在类型IList<T>
不兼容的变量中。 Unfortunately I cannot suggest a good alternative because I have no idea how you are planning to use these classes or what your overall goal is; 不幸的是,由于我不知道您打算如何使用这些类或您的总体目标是什么,我无法提出一个好的选择。 but I can make a suggestion with a disclaimer that it is hacky and should probably only be used if you really know what you are doing:
但我可以用一个声明,这是哈克 ,应该大概只有当你真的知道你在做什么使用建议:
public static class ListUtils
{
public static object CreateListOfPersistent(Type elementType)
{
if (!typeof(Persistent).IsAssignableFrom(elementType))
throw new ArgumentException("elementType must derive from Persistent.", "elementType");
var listType = typeof(ListOfPersistent<>).MakeGenericType(elementType);
return Activator.CreateInstance(listType);
}
}
// ...
if (Extensions.IsPersistent<T>())
list = (IList<T>) ListUtils.CreateListOfPersistent(typeof(T));
else
list = new ListOfNonPersistent<T>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.