简体   繁体   English

如何使用接口作为通用参数?

[英]How to use interface as a generic parameter?

I have a generic class: 我有一个通用类:

class JobDetails<IJobRequirement>{}
class SpecialRequirement: IJobRequirement{}

I'm unable to assign the values of type JobDetails<SpecialRequirement> to variables of type JobDetails<IJobRequirement> . 我无法类型的值分配JobDetails<SpecialRequirement>到类型的变量JobDetails<IJobRequirement> Is this possible in C# or am I missing something basic ? 这在C#中可能吗,还是我缺少基本的东西?

Generally Foo<A> and Foo<B> do not share a common ancestry. 通常, Foo<A>Foo<B>不具有共同的血统。 They share a common generic type definition, but that does not mean they are assignable even if public class B : A . 它们共享一个通用的泛型类型定义,但这并不意味着即使public class B : A也可以分配它们。

You seem to be looking for Co- and Contravariance. 您似乎正在寻找协方差和协方差。 A mechanism for generics in C# that lets you define compatibility between different types. C#中的泛型机制,可让您定义不同类型之间的兼容性。 However this only works for generic interfaces. 但是,这仅适用于通用接口。

For example 例如

public interface IJobDetails<out TRequirement>
   where TRequirement : IJobRequirement
{
    TRequirement Requirement { get; }
}

public class JobDetails<TRequirement> : IJobDetails<TRequirement>
{
    public TRequirement Requirement { get; set; }
}

public void Test()
{
    IJobDetails<IJobRequirement> a = new JobDetails<SpecificRequirement>();
}

However using the modifier in or out limits whether you can use the type only as a return value or a method argument. 但是使用修改器inout限制是否可以使用该类型作为返回值方法参数。

This is the reason why you an assign IEnumerable<B> to IEnumerable<A> if public class B : A because IEnumerable is declared as IEnumerable<out T> . 这就是为什么如果public class B : AIEnumerable<B>分配给IEnumerable<A> public class B : A原因,因为IEnumerable被声明为IEnumerable<out T>

For further information I recommend reading the following Blog: http://tomasp.net/blog/variance-explained.aspx/ 有关更多信息,我建议阅读以下博客: http : //tomasp.net/blog/variance-explained.aspx/

You can put constraints on Type Parameters : 您可以对类型参数施加约束

interface IJobRequirement
{ }

class SpecialRequirement : IJobRequirement
{ }

class JobDetails<T> where T : IJobRequirement
{ }

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

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