【发布时间】:2022-12-06 21:23:24
【问题描述】:
我有以下方法
public static EnumerableAssertions<T> AssertThat<T>(IEnumerable<T> collection)
{
Debug.WriteLine("Enumerable!");
return new EnumerableAssertions<T>(collection);
}
public static ObjectAssertions<T> AssertThat<T>(T value) where T : class
{
Debug.WriteLine("Generic fallback!");
return new ObjectAssertions<T>(value);
}
但是为什么下面的调用解析为通用回退?
List<object> list = null;
AssertThat(list);
根据我的理解,IEnumerable<T> 的重载应该比通用的 T : class 更具体,但 C# 似乎对此有不同的看法。如果我为精确的输入 List<T> 它工作得很好,但我当然不想为每个继承 IEnumerable<T> 的类型添加特定的重载
[编辑] 这个也不起作用:
public static EnumerableAssertions<TCollection> AssertThat<TCollection, T>(TCollection collection) where TCollection : IEnumerable<T>
{
Debug.WriteLine("Enumerable #2!");
return new EnumerableAssertions<T>(collection);
}
【问题讨论】:
-
无论如何你为什么要使用
List<object>? -
@Deleted 如果您更喜欢它,请将其设为 List<string> 并且问题不会改变。这是一个例子。
-
顺便说一句,如果您提供
string,您希望它选择哪个重载?请记住,那种类型发生成为IEnumerable<char>,但这不是最常见的思考方式。 -
苹果和橙子.
AssertThat<T>(T value)包含显式约束where T : class而AssertThat<T>(IEnumerable<T> collection)具有不完全没有明确的约束。AssertThat(list);最有可能解析为通用类型,因为List<>是引用类型,比不受限制的IEnumerable<T>更符合where T : class -
“我知道这些是苹果和橘子,但即使是超载”- 无关紧要。问题出在你的代码上,而不是他们的。
标签: c# overloading overload-resolution