有没有办法在变量类型IReturn<IFeatureX>
中存储IReturn<T> ... where T : class, IFeatureX
,或者你能解释为什么不能这样做吗?
假设我有一个容器构造函数:
public ContainerX(IReturn<IFeatureX> body) : this()
{
Body = body;
}
我想说的是,IFeatureX 也扩展了class
,我尝试将构造函数更改为私有并使用:
public static ContainerX CreateInstance<T>(IReturn<T> instance)
where T : class, IFeatureX => new ContainerX { Body = instance };
但是c#不知道IReturn<T> ... where T : class, IFeatureX
是IReturn<IFeatureX>
。
看来我不能投射或安全投射它。
我不能使用object
或dynamic
IFeatureX
因为它实际上是IProtobufBody
的,它是一个标签接口,我用它来使集成测试级别保证在容器中存储实例的所有程序集都定义了 protobuf 协定。
您只需通过将其声明为IReturn<out T>
来IReturn<T>
协变。您可以在此处阅读有关协方差和逆变的更多信息。
这是一个协方差和逆变的问题(见这里(。
假设您有一个名为Dog
的类,它继承自Animal
,请考虑以下代码:
List<Dog> l = new List<Dog>();
List<Animal> la = l;
la.Add(new Giraffe()); // this is not allowed
此示例说明了默认情况下不允许这样做的原因。
有关键字in
和out
,可让您使用逆变和协方差,例如IReturn<in T>
或IReturn<out T>
。
使用in
时,可以将IReturn<Object>
对象存储在类型为IReturn<Class>
的变量中,并在使用T
作为输入变量 Type 的IReturn
中定义函数。
使用out
时,可以将IReturn<Class>
对象存储在类型IReturn<Object>
的变量中,并在使用T
作为返回类型的IReturn
中定义函数。
如果需要T
在某些函数中是输入变量类型,而在其他函数中是返回类型,那么您只能使用确切的类。
抱歉,其他答案不适用。在这种特殊情况下,答案是
IReturn<T> ... where T : FeatureBase
并让实例扩展功能库。