4

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

话虽如此,我仍然无法弄清楚如何在我的特定用例中解决问题。我需要在集合中聚合“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
    {
    }
}

上面的代码失败并出现以下编译错误:

错误 CS1503:参数 1:无法从“Covariance.GenericClass”转换为“Covariance.GenericClass”

错误 CS1503:参数 1:无法从“Covariance.GenericClass”转换为“Covariance.GenericClass”

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

4

1 回答 1

4

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

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>());
    }
}
于 2016-11-23T08:17:31.817 回答