如何使用interface作为通用参数?

时间:2018-04-30 10:20:46

标签: c# .net generics inheritance

我有一个通用类:

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

我无法将类型JobDetails<SpecialRequirement>的值分配给JobDetails<IJobRequirement>类型的变量。这在C#中是可能的还是我遗漏了一些基本的东西?

2 个答案:

答案 0 :(得分:5)

通常Foo<A>Foo<B>不共享共同的祖先。它们共享一个共同的泛型类型定义,但这并不意味着它们即使public class B : A也可以分配。

你似乎在寻找合作和反演。 C#中的泛型机制,允许您定义不同类型之间的兼容性。但是这仅适用于通用接口。

例如

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>();
}

但是,使用修饰符inout会限制您是否可以使用类型作为返回值方法参数。< / p>

这就是您IEnumerable<B> IEnumerable<A> public class B : A IEnumerable的原因,因为IEnumerable<out T>被声明为 def fn1(self): global NUM NUM = 1 print "fn1 = ", NUM def fn2(self): global NUM NUM = 2 print "fn2 = ", NUM def fn3(self): global NUM NUM = 3 print "fn3 = ", NUM NUM = 0 fn1(NUM) fn2(NUM) fn3(NUM)

有关详细信息,我建议您阅读以下博客:http://tomasp.net/blog/variance-explained.aspx/

答案 1 :(得分:2)

你可以放constraints on Type Parameters

interface IJobRequirement
{ }

class SpecialRequirement : IJobRequirement
{ }

class JobDetails<T> where T : IJobRequirement
{ }