【发布时间】:2018-06-11 19:50:56
【问题描述】:
在我看来,C# 编译器中存在错误/不一致。
这很好用(第一个方法被调用):
public void SomeMethod(string message, object data);
public void SomeMethod(string message, params object[] data);
// ....
SomeMethod("woohoo", item);
但这会导致“以下方法之间的调用不明确”错误:
public void SomeMethod<T>(string message, T data);
public void SomeMethod<T>(string message, params T[] data);
// ....
SomeMethod("woohoo", (T)item);
我可以完全使用转储第一种方法,但由于这是一个对性能非常敏感的库,并且大约 75% 的时间将使用第一种方法,我宁愿不总是将东西包装在一个数组中并实例化一个如果只有一个项目,迭代器会遍历一个 foreach。
拆分成不同的命名方法充其量是 IMO 的混乱。
想法?
编辑:
我猜 Andrew 可能正在做点什么。
完整示例:
public static class StringStuffDoer
{
public static string ToString<T>(T item1, T item2)
{
return item2.ToString() + item1.ToString();
}
public static string ToString<T>(T item, params T[] items)
{
StringBuilder builder = new StringBuilder();
foreach (T currentItem in items)
{
builder.Append(currentItem.ToString());
}
return item.ToString() + builder.ToString();
}
public static void CallToString()
{
ToString("someString", null); // FAIL
ToString("someString", "another string"); // SUCCESS
ToString("someString", (string)null); // SUCCESS
}
}
我仍然认为需要演员阵容很奇怪 - 这个电话并不模棱两可。如果将 T 替换为字符串或对象或任何非泛型类型,它会起作用,那么为什么它不适用于泛型呢?它正确地找到了两种可能的匹配方法,所以我相信按照规范,它应该尽可能选择不使用参数的方法。如果我在这里错了,请纠正我。
(不是这样)最终更新:
很抱歉带你们参加这个 tyraid,我显然已经盯着这个太久了......一晚上看泛型和参数太多了。非通用版本也会引发模棱两可的错误,我只是在我的模型测试中关闭了方法签名。
真正的最终更新:
好的,这就是我的非通用测试中没有出现问题的原因。我使用“对象”作为类型参数。 SomeMethod(object) 和 SomeMethod(params object[]) 不会抛出模棱两可的错误,我猜“null”会自动转换为“object”。我会说有点奇怪,但也许可以理解。
所以,奇怪的是,这个调用确实有效:
SomeMethod<object>("someMessage", null);
【问题讨论】:
-
请发布一个简短但完整的程序来演示该问题,并告诉我们您使用的是哪个版本的 C#。
-
如果你不将item转换成T,它是如何工作的?如果在您将项目声明为 T 类型之前的某个时间点,它是否按预期工作?
-
请注意,“错误”是实际行为与指定行为之间的差异。实际行为与预期行为之间的差异将是“奇怪”或“意外结果”。您是否检查了相应的规范?
-
我只是把演员放在那里,向您展示第二个示例中的项目是类型 T。演员阵容没有任何区别。
-
@Mike M:如果你不写实际的调用而不是
SomeMethod("woohoo", (T)item);(至少T和item是什么),我们不可能帮助你。跨度>
标签: c# generics parameters