IEnumerable 的generics方法的重载?
我想要一个generics方法的两个重载:
public ReturnType DoStuff(T thing) {...} public ReturnType DoStuff(IEnumerable things) {...}
麻烦当然是IEnumerable
本身就是一个匹配第一个签名的类型,所以当我尝试将一个集合传递给这个方法时,它会调用第一个重载。
显然,我可以用不同的方法命名方法以消除歧义。 但是看到方法基本上做同样的事情,我想把它们作为重载。
是否有某种方法在第一个签名中定义T
,以便它不接受IEnumerable
作为参数?
这是一个黑客,但你可以滥用扩展方法仅在非扩展方法中找不到匹配时考虑的事实。
class MyClass { public ReturnType DoStuff (IEnumerable things) { ... } public ReturnType DoStuffSingle (T thing) { ... } } static class MyClassExtensions { public static ReturnType DoStuff (this MyClass myClass, T thing) => myClass.DoStuffSingle(thing); }
在此之后,给出一个MyClass myClass;
:
-
myClass.DoStuff(123);
调用扩展方法采用int
-
myClass(new[] {123});
使用IEnumerable
调用实例方法 -
myClass("123");
使用IEnumerable
调用实例方法 -
myClass(t);
,其中t
是无约束的通用参数类型T
,无论T
实现哪个接口,都调用带有T
的扩展方法。
在我看来,最后两个表明你可能不应该继续沿着这条路走下去,但是没有什么可以阻止你不同意并且不管怎样。
我不认为有一种方法可以说除了“除了X之外的所有东西”之外你想要但是你可以使用通用约束来指定T
应该是什么样的:
public ReturnType DoStuff (T thing) where T : IYourInterface {...} public ReturnType DoStuff (IEnumerable things) where T : IYourInterface {...}
我认为这样做是有意义的(没有添加更多代码),因为generics被编译为实际的类。 如果你指定“除了X之外的所有东西”那么它应该编译成什么? 它有什么function?..
为了更好地理解为什么要使用T
而不是仅传递IYourInterface
参数,请参阅接口作为类型约束和接口作为参数的区别? 。 此外, 这可能会提供更多解释