【问题标题】:How to use interface as a generic parameter?如何使用接口作为泛型参数?
【发布时间】:2018-04-30 10:20:46
【问题描述】:

我有一个通用类:

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

我无法将JobDetails&lt;SpecialRequirement&gt; 类型的值分配给JobDetails&lt;IJobRequirement&gt; 类型的变量。这在 C# 中是可能的还是我错过了一些基本的东西?

【问题讨论】:

  • 你能发布你所有的代码吗?第一个类似乎有一个名为 IJobRequirement 的泛型类型,这与将泛型类型设置为具有该名称的接口不同。

标签: c# .net generics inheritance


【解决方案1】:

通常Foo&lt;A&gt; 和Foo&lt;B&gt; 没有共同的祖先。它们共享一个通用的泛型类型定义,但这并不意味着即使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>();
}

但是,使用修饰符 in 或 out 会限制您是否可以将类型仅用作返回值或方法参数。

这就是为什么如果public class B : A 将IEnumerable&lt;B&gt; 分配给IEnumerable&lt;A&gt; 的原因,因为IEnumerable 被声明为IEnumerable&lt;out T&gt;。

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

【讨论】:

【解决方案2】:

你可以把constraints on Type Parameters:

interface IJobRequirement
{ }

class SpecialRequirement : IJobRequirement
{ }

class JobDetails<T> where T : IJobRequirement
{ }

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
相关资源
最近更新 更多