通用接口约束

时间:2013-11-20 10:13:43

标签: c# generics interface casting

我有一个关于泛型和创建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
        }
    }
}

我读到了共同和逆变,但我必须遗漏一些东西,或者它没有什么可以做我正在尝试的东西,或者它只是不起作用我想要做的。

我虽然可以将测试从测试变为测试,因为TImple继承自ITest。

3 个答案:

答案 0 :(得分:3)

应该是

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

然后创建Test的实例

var s = new Test<Timpl>();

修改

基于以下评论。好的,现在你正在处理协方差和逆变。如果您需要指定

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

然后它无法工作,因为只有接口和委托的泛型类型参数可以标记为协变或逆变。

但是,您可以通过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

答案 1 :(得分:1)

试试这个。

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
        }
    }
}

答案 2 :(得分:0)

我想我理解你的问题。您可以在以下MSDN链接中阅读有关协方差和逆变的信息:http://msdn.microsoft.com/en-us/library/vstudio/ee207183.aspx

我的问题解决方案如下所示

界面ITest     {     }

class TImpl:ITest
{

}

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

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

正如您所看到的,我已经在Test类中添加了接口,并且我将Type参数T标记为out。现在您可以执行以下操作:

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

我希望这会有所帮助