与generics参数的接口与使用generics方法的接口
假设我有这样的界面和具体实现
public interface IMyInterface { T My(); } public class MyConcrete : IMyInterface { public string My() { return string.Empty; } }
所以我为strings
创建MyConcrete实现,我可以为int
提供一个更具体的实现。 那没关系。 但是,让我们说,我想做同样的事情,但使用通用方法,所以我有
public interface IMyInterface2 { T My(); } public class MyConcrete2 : IMyInterface2 { public string My() { throw new NotImplementedException(); } }
所以我有相同的IMyInterface2
,但它通过T My()
定义了通用行为。 在我的具体类中,我想实现My
行为,但对于具体的数据类型 – string
。 但C#不允许我这样做。
我的问题是为什么我不能这样做? 换句话说,如果我可以创建MyInterface
具体实现作为MyClass : MyInterface
并在此时停止泛化,为什么我不能用generics方法T My()
?
您的通用方法实现也必须是通用的,因此它必须是:
public class MyConcrete2 : IMyInterface2 { public T My() { throw new NotImplementedException(); } }
为什么你不能在这里做My
? 因为接口契约需要一个方法,可以使用任何类型参数T
调用,并且您必须履行该合同。
为什么你不能在这一点上阻止一般性 ? 因为它会导致以下情况:
类声明:
public interface IMyInterface2 { T My(t value); } public class MyClass21 : IMyInterface2 { public string My(string value) { return value; } } public class MyClass22 : IMyInterface2 { public int My(int value) { return value; } }
用法:
var item1 = new MyClass21(); var item2 = new MyClass22(); // they both implement IMyInterface2, so we can put them into list var list = new List(); list.Add(item1); list.Add(item2); // iterate the list and call My method foreach(IMyInterface2 item in list) { // item is IMyInterface2, so we have My() method. Choose T to be int and call with value 2: item.My(2); // how would it work with item1, which has My implemented? }
当您编写通用方法时,定义用于保留占位符。 调用方法时,实际类型会显示在图片中。 所以相反你应该写
public T My() { throw new NotImplementedException(); }
当你调用方法时,你可以在那里使用字符串。
因为您的接口声明了一个通用方法T My
,但您的实现没有实现具有该特定签名的函数。
为了达到你想要的效果,你需要在第一个例子中为界面提供T generic参数:
public interface IMyInterface2 { T My(); } public class MyConcrete2 : IMyInterface2 { public string My() { throw new NotImplementedException(); } }
您的解决方案不起作用有两个原因。
首先,界面是合同。 当您实现IMyInterface2
您保证将实现名为My
的函数,该函数接受generics类型参数并返回该类型。 MyConcrete2
不会这样做。
其次,C#generics不允许任何类型的参数专门化。 (我希望C#支持这个。)这是C ++模板中常见的事情,你的例子可以编译,但如果他们没有用string
调用My
, MyConcrete2
任何用法MyConcrete2
将无法编译。