简体   繁体   English

阴影泛型方法 class 约束

[英]Shadowing generic method class constraint

Is there a way store IReturn<T>... where T: class, IFeatureX in variable type IReturn<IFeatureX> or can you explain why this cannot be done?有没有办法存储IReturn<T>... where T: class, IFeatureX在变量类型IReturn<IFeatureX>或者你能解释为什么不能这样做吗?


Lets say that I have a container constructor:假设我有一个容器构造函数:

public ContainerX(IReturn<IFeatureX> body) : this()
{
    Body = body;
}

I want to say that IFeatureX extends also class , I have tried changing the constructor to private and using:我想说 IFeatureX 也扩展class ,我尝试将构造函数更改为私有并使用:

public static ContainerX CreateInstance<T>(IReturn<T> instance) 
  where T : class, IFeatureX => new ContainerX { Body = instance };

However c# does not know that IReturn<T>... where T: class, IFeatureX is IReturn<IFeatureX> .但是 c# 不知道IReturn<T>... where T: class, IFeatureXIReturn<IFeatureX>

It seems that I cannot cast or safe cast it.看来我无法施放或安全施放它。

I cannot use object or dynamic because IFeatureX is actually IProtobufBody and it is a label interface that I use to make a integration test level guarantee that all assemblies that store instances in the container have a protobuf contract defined.我不能使用objectdynamic的,因为IFeatureX实际上是IProtobufBody并且它是一个 label 接口,我用来进行集成测试级别保证在容器中存储实例的所有程序集都定义了 protobuf 合同。

You simply need to make IReturn<T> covariant by declaring it as IReturn<out T> .您只需要通过将IReturn<T>声明为IReturn<out T>来使其成为协变的。 You can read more about covariance and contravariance here .您可以在此处阅读有关协变和逆变的更多信息。

This is a problem of covariance and contravariance ( see here ).这是一个协变和逆变的问题( 见这里)。

Lets say you have a class called Dog which inherits from Animal , consider the following code:假设您有一个名为Dog的 class 继承自Animal ,请考虑以下代码:

List<Dog> l = new List<Dog>();
List<Animal> la = l;
la.Add(new Giraffe()); // this is not allowed

This example shows why it is not allowed by default.此示例说明了为什么默认情况下不允许这样做。

There are the keywords in and out that lets you use the contravariance and covariance like IReturn<in T> or IReturn<out T> .有关键字inout可让您使用IReturn<in T>IReturn<out T>等逆变和协变。

When you use in , then you can store a IReturn<Object> object in a variable of type IReturn<Class> and define functions in IReturn that use T as input variable Type.当您使用in ,您可以将IReturn<Object> object 存储在IReturn<Class>类型的变量中,并在IReturn中定义使用T作为输入变量类型的函数。

When you use out , then you can store a IReturn<Class> object in a variable of type IReturn<Object> and define functions in IReturn that use T as return Type.当您使用out ,您可以将IReturn<Class> object 存储在IReturn<Object>类型的变量中,并在IReturn中定义使用T作为返回类型的函数。

If you need T to be an input variable type in some functions and a return type in other functions, then you can only work with the exact class.如果您需要T成为某些函数中的输入变量类型和其他函数中的返回类型,那么您只能使用确切的 class。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM