【问题标题】:Can´t have two methods with same signature but different generic constraints不能有两个方法具有相同的签名但不同的通用约束
【发布时间】:2016-12-21 18:03:11
【问题描述】:

我有这个方法:

public IEnumerable<MyType> DoSomething<TResult>(Func<MyType, TResult> func) 
    where TResult : AnotherType

现在我希望这个方法也出现在IEnumerable&lt;AnotherType&gt; 中。所以我写了这个显然不能编译:

public IEnumerable<MyType> DoSomething<TResult>(Func<MyType, TResult> func) 
    where TResult : IEnumerable<AnotherType>

我得到编译器错误:

已声明具有相同签名的成员

我读过Member with the same signature already defined with different type constraints,它处理成员与另一种返回类型。但是在我的示例中,我不区分方法返回类型,而是区分它的参数列表,首先是Func&lt;MyType, TResult&gt;,第二个是Func&lt;IEnumerable&lt;MyType&gt;, TResult&gt;。但是编译器无法处理。

除了为第二个示例使用另一个方法名称之外,还有其他方法吗?

【问题讨论】:

  • 通用约束不是方法签名的一部分,因此您不能创建具有不同约束的相同方法。
  • 如果你仍然在定义类型,为什么它是通用的,而不是一个Func&lt;MyType, AnotherType&gt;和另一个Func&lt;MyType, IEnumerable&lt;AnotherType&gt;&gt;
  • @Dr.Coconut 我已经在我的帖子中提到过这篇文章。
  • @HimBromBeere 哎呀,没注意到链接,抱歉。
  • This Eric Lippert 博客中的帖子是关于该主题的有趣读物。 cmets 表明,设计决定有些争议。

标签: c# generics


【解决方案1】:

确实不允许两个方法重载仅因泛型约束而不同。

在你的情况下,我想知道你是否甚至需要 TResult(也由 Alfie Goodacre 评论)因为 IEnumerable&lt;out T&gt;T 中是协变的,而 Func&lt;in T1, out TResult&gt;TResult 中是协变的。

那就试试吧:

public IEnumerable<MyType> DoSomething(Func<MyType, AnotherType> func) 

和:

public IEnumerable<MyType> DoSomething(Func<MyType, IEnumerable<AnotherType>> func) 

由于提到的协方差,在调用上述重载时,可以使用比AnotherType 更派生的类。


另一种选择:

public IEnumerable<MyType> DoSomething<TResult>(Func<MyType, TResult> func) 
  where TResult : AnotherType

和:

public IEnumerable<MyType> DoSomething<TResult>(Func<MyType, IEnumerable<TResult>> func) 
  where TResult : AnotherType

在这种替代方法中,两个重载中的签名不同且约束相同。即使AnotherTypeinterface 并且TResult 是实现接口的struct(值类型),这也可以工作,在这种情况下协方差(out Tout TResult)不起作用。

【讨论】:

  • 天哪,最简单的解决方案总是最好的。
猜你喜欢
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-31
相关资源
最近更新 更多