IEnumerable <t>的泛型方法的重载?

时间:2016-10-09 11:25:12

标签: c# generics

我希望有两个泛型方法的重载:

^.*POST .*(wp-login|xmlrpc)\.php.*(403|499)*

麻烦当然是public ReturnType<T> DoStuff<T>(T thing) {...} public ReturnType<T> DoStuff<T>(IEnumerable<T> things) {...} 本身就是一个与第一个签名匹配的类型,所以当我尝试将一个集合传递给这个方法时,它会调用第一个重载。

显然,我可以用不同的方式命名方法以消除歧义。但是看到方法基本上做同样的事情,我想把它们作为重载。

是否有某种方法可以在第一个签名中定义IEnumerable<T>,以便接受T作为参数?

2 个答案:

答案 0 :(得分:4)

这是一个黑客攻击,但你可以滥用扩展方法仅在非扩展方法中找不到匹配时考虑的事实。

class MyClass {
  public ReturnType<T> DoStuff<T>(IEnumerable<T> things) { ... }
  public ReturnType<T> DoStuffSingle<T>(T thing) { ... }
}

static class MyClassExtensions {
  public static ReturnType<T> DoStuff<T>(this MyClass myClass, T thing)
    => myClass.DoStuffSingle(thing);
}

在此之后,给出MyClass myClass;

  • myClass.DoStuff(123);使用int
  • 调用扩展方法
  • myClass(new[] {123});调用IEnumerable<int>
  • 的实例方法
  • myClass("123");调用IEnumerable<char>
  • 的实例方法
  • myClass(t);,其中t是无约束的通用参数类型T,无论T实现哪个接口,都会调用T的扩展方法。

在我看来,最后两个表明你可能不应该继续沿着这条路走下去,但是没有什么可以阻止你不同意并且不管怎么说。

答案 1 :(得分:0)

我认为没有办法说除了“X以外的所有内容”,但您可以使用generic constraints来指定T应该是什么样的内容:

public ReturnType<T> DoStuff<T>(T thing) where T : IYourInterface {...}    
public ReturnType<T> DoStuff<T>(IEnumerable<T> things) where T : IYourInterface {...}

我认为这样做是没有意义的(没有添加更多代码),因为泛型被编译为实际的类。如果你指定“除了X之外的所有东西”那么它应该编译成什么?它有什么功能?..

要更好地了解使用T的原因而不是仅传递IYourInterface参数,请参阅Difference between interface as type constraint and interface as parameter?。此外,this可能会提供更多解释