c# - 我已经阅读了所有关于协变、逆变和不变的内容,但我仍然不知道如何设计我的代码

标签 c# generics covariance nested-generics invariance

在发布这篇文章之前,我已经尽可能多地搜索和阅读/研究了似乎合理的内容。我发现了类似的问题,但大多数帖子实际上更多地涉及将“派生类型列表”传递给需要“基本类型列表”的函数调用。我可以欣赏动物的例子,并且感觉在学习之后我有了更好的理解。

话虽如此,我仍然无法弄清楚如何解决我的特定用例。我需要在集合中聚合 “GenericClass of TestInterface(s)” 的实例。我已经在下面复制/粘贴了我最大的努力,这似乎是完成任务的最佳方式。

namespace Covariance
{
    class Program
    {

        protected static ISet<GenericClass<TestInterface>> set = new HashSet<GenericClass<TestInterface>>();

        static void Main(string[] args)
        {
            set.Add(new GenericClass<A>());
            set.Add(new GenericClass<B>());
        }
    }

    class GenericClass<TemplateClass> where TemplateClass : TestInterface
    {
        TemplateClass goo;
    }

    public interface TestInterface
    {
        void test();
    }
    public class A : TestInterface
    {
        public void test()
        {
        }
    }

    class B : A
    {
    }
}

以上代码因以下编译错误而失败:

error CS1503: Argument 1: cannot convert from 'Covariance.GenericClass' to 'Covariance.GenericClass'

error CS1503: Argument 1: cannot convert from 'Covariance.GenericClass' to 'Covariance.GenericClass'

任何帮助/指导或相关链接将不胜感激。如果这是一个重复的问题,我再次表示歉意。谢谢!

最佳答案

您只能在泛型接口(interface)上声明变体修饰符(in、out),而不能在类型上声明。因此,解决此问题的一种方法是为您的 GenericClass 声明接口(interface),如下所示:

interface IGenericClass<out TemplateClass> where TemplateClass : TestInterface {
    TemplateClass goo { get; }
}
class GenericClass<TemplateClass> : IGenericClass<TemplateClass> where TemplateClass : TestInterface
{
    public TemplateClass goo { get; }
}

然后

class Program {
    protected static ISet<IGenericClass<TestInterface>> set = new HashSet<IGenericClass<TestInterface>>();

    static void Main(string[] args) {
        set.Add(new GenericClass<A>());
        set.Add(new GenericClass<B>());
    }
}

关于c# - 我已经阅读了所有关于协变、逆变和不变的内容,但我仍然不知道如何设计我的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40758996/

相关文章:

c# - 使用对象而不是泛型

c# - 删除子窗体上的顶部栏

c# - 分析 WPF + WCF + EF 应用程序

.net - 为什么运行时将泛型类型显示为 "GenericType` n"?

java - 持久化合约设计 : Single generic interface vs. 几个专用接口(interface)

c# - 同时使用值和引用类型的泛型的协方差解决方法

matlab - 在 Matlab 中计算协方差矩阵

c# - 该类型不能用作泛型类型或方法 'T' 中的类型参数 'BaseController<T>' 。没有隐式引用

c# - 为什么 WPF 组合框项目源转换器获取整个集合而不是项目?

c# - 服务定位协议(protocol)的示例客户端实现?