简体   繁体   English

通用接口约束

[英]Generic interface constraint

I have a question about generics and the use of interfaces cast when creating concret classes: 我有一个关于泛型和在创建concret类时使用接口转换的问题:


namespace MyNamespace
{
    interface ITest
    {

    }

    class Timpl : ITest
    {

    }

    class Test<T> where T : ITest
    {
        public T get()
        {
            return default(T);
        }
    }

    class MyClass
    {
        public MyClass()
        {
            Test<ITest> s = new Test<Timpl>(); //Does not compile
        }
    }
}

I read up on co- and contravariant, but I must be missing something, or it has nothing to do what I'm trying, or it just doesnt work what I'm trying to do. 我阅读了协变量和逆变量,但我必须缺少某些东西,或者它与我正在尝试执行的操作无关,或者它根本无法执行我正在尝试执行的操作。

I though I could make the cast from Test to Test because TImple inherits from ITest. 尽管我可以在测试之间进行转换,因为TImple继承自ITest。

It should be 它应该是

class Test<T> where T : ITest
{
    public T get()
    {
        return default(T);
    }
}

Then create an instance of Test like 然后创建一个Test实例,例如

var s = new Test<Timpl>();

EDIT: 编辑:

Based on the comment below. 根据以下评论。 Ok, now you are dealing with covariance and contravariance. 好的,现在您正在处理协方差和逆方差。 If you need to specify 如果需要指定

Test<ITest> s = new Test<Timpl>();

then it can't work because only generic type parameters of interfaces and delegates can be marked as covariant or contravariant. 那么它就无法工作,因为只能将接口和委托的通用类型参数标记为协变或逆变。

However, you could solve it by making Test implement an interface. 但是,您可以通过使Test实现一个接口来解决它。

interface ITestClass<out T>
{
    T get();
}

class Test<T> : ITestClass<T> where T : ITest
{
    public T get()
    {
        return default(T);
    }
}

ITestClass<ITest> s = new Test<Timpl>(); // Does compile

try this. 尝试这个。

namespace MyNamespace
{
    interface ITest
    {
    }

    class Timpl : ITest
    {
    }

    class Test<T> where T : ITest
    {
        public T get()
        {
            return default(T);
        }
    }

    public class mycls : ITest
    {
    }

    class MyClass
    {
        public MyClass()
        {
            Test<mycls> s = new Test<mycls>(); //will compile
        }
    }
}

I think I understand your problem. 我想我明白你的问题。 You can read about covariance and contravariance at the following MSDN link : http://msdn.microsoft.com/en-us/library/vstudio/ee207183.aspx 您可以在下面的MSDN链接中了解协方差和协方差: http : //msdn.microsoft.com/zh-cn/library/vstudio/ee207183.aspx

My Solution to your problem looks like this 我对您问题的解决方案如下所示

interface ITest { } ITest {}接口

class TImpl:ITest
{

}

interface ITest<out T>
{
    T get();
}

class Test<T>:ITest<T> 
          where T:ITest
{
    public T get()
    {
        return default(T);
    }
}

As you can see , I've added and interface over your Test class and I've marked the Type argument, T, as out. 如您所见,我已经在您的Test类上添加了接口,并将Type参数T标记为out。 Now you can do the following: 现在,您可以执行以下操作:

 ITest<ITest> t = new Test<TImpl>();

I hope this helps 我希望这有帮助

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

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