2016-05-30 40 views
0

我想编写一个接口,允许自由的实现。基本上我不知道返回类型的方法的参数类型。我只是希望派生类使用相同的方法名称和参数号来实现此合约。编译错误与基本类型与接口的通用方法的实现

所以,我可以这样做:

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(); 
    } 
} 

谢谢

+0

但是你的任何实现都不能满足这个接口。例如在对象Learn(object param)中,我必须能够传递任何“param”(因为它是object类型的),但是你的byte [] Learn(string param)只允许我传递一个字符串,所以它不满足界面。 – Evk

+0

我认为泛型的主要观点是你试图规避的。你*必须*最终指定一个类型。我想你想让''''''''和'''Recognize'''对象通用,而不是方法或接口。然后那些可以采取任何你想要的类型,你可以保持界面清洁(和方法签名)! – Ruskin

+0

你有代码示例来分享吗?我不确定要理解。我想要的是在我的程序中使用我的接口,并通过使用依赖注入在启动时传递良好的实现。像这样,我可以很容易地改变我使用的实现。 –

回答

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

不会做你在想什么 - FooExampleClassFooExampleClass2不是类型,而是可以实例化为任何类的类型参数。这意味着客户可以这样做:

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

您的代码只显示工作,因为它什么都不做。

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

+0

好的,谢谢你的回答。我认为在我的情况下可能只使用通用方法而不使用通用接口,但似乎不是。随着方法数量的增长,实现类看起来非常难看,难以阅读 –