使用接口的泛型方法实现的基元类型的编译错误

时间:2016-05-30 08:51:15

标签: c# generics interface implementation primitive-types

我想编写一个允许实现自由的接口。基本上我不知道返回类型既不是方法的param类型。我只是希望派生类用相同的方法名和参数号来实现这个契约。

所以我可以这样做:

public interface IImageRecognitionEngine<TFoo0, TFoo1, TFoo2, TFoo3>
{
    TFoo0 Learn(TFoo1 param);
    TFoo2 Recognize(TFoo3 param);
}

public class FooImageRecognitionEngine : IImageRecognitionEngine<byte[], string, List<double>, string>
{
    public byte[] Learn(string param)
    {
        throw new NotImplementedException();
    }

    public List<double> Recognize(string param)
    {
        throw new NotImplementedException();
    }
}

但我更喜欢泛型方法而不是整个界面。但我不明白为什么我能做到这一点:

public interface IImageRecognitionEngine2
{
    TFoo0 Learn<TFoo0, TFoo1>(TFoo1 param);
    TFoo2 Recognize<TFoo2, TFoo3>(TFoo3 param);
}

public class FooExampleClass
{

}

public class FooExampleClass2
{

}

public class Foo1ImageRecognitionEngine2 : IImageRecognitionEngine2
{
    public FooExampleClass Learn<FooExampleClass, FooExampleClass2>(FooExampleClass2 param)
    {
        throw new NotImplementedException();
    }

    public FooExampleClass Recognize<FooExampleClass, FooExampleClass2>(FooExampleClass2 param)
    {
        throw new NotImplementedException();
    }
}

但是对于原始类型,编译器会给我错误:

public class Foo2ImageRecognitionEngine2 : IImageRecognitionEngine2
{
    public byte[] Learn<byte[], string>(string param)
    {
        throw new NotImplementedException();
    }

    public List<double> Recognize<List<double>, string>(string param)
    {
        throw new NotImplementedException();
    }
}

当我实例化类实现的对象时,我不希望能够选择要使用的类型。例如,我不想写这样的实现:

public class Foo2ImageRecognitionEngine2 : IImageRecognitionEngine2
{
    public TFoo0 Learn<TFoo0, TFoo1>(TFoo1 param)
    {
        throw new NotImplementedException();
    }

    public TFoo2 Recognize<TFoo2, TFoo3>(TFoo3 param)
    {
        throw new NotImplementedException();
    }
}

能够做到这一点:

var fooEngine = new Foo2ImageRecognitionEngine2();
fooEngine.Learn<string, int>(52);

这也不起作用:

public interface IImageRecognitionEngine3
{
    object Learn(object param);
    object Recognize(object param);
}

public class Foo1ImageRecognitionEngine3 : IImageRecognitionEngine3
{
    public byte[] Learn(string param)
    {
        throw new NotImplementedException();
    }

    public List<double> Recognize(string param)
    {
        throw new NotImplementedException();
    }
}

谢谢

1 个答案:

答案 0 :(得分:2)

public FooExampleClass Learn<FooExampleClass, FooExampleClass2>(FooExampleClass2 param)
{
    throw new NotImplementedException();
}

不符合您的想法 - FooExampleClassFooExampleClass2不是类型,而是可以实例化到任何类的类型参数。这意味着客户可以这样做:

var e = new Foo1ImageRecognitionEngine2();
e.Learn<string, object>(new object());

您的代码似乎只能起作用,因为它什么都不做。

这样的通用方法必须适用于客户选择的任何参数,因此无法限制参数对特定参数起作用。如果你想这样做,你需要将它们移动到第一个例子中的接口定义。