重载 null 的歧义问题

9
我有以下几种方法:
  void Method(string param1, string param2);
  void Method(string param1, object param2);

当我使用以下方式调用该方法时:
  method("string", null);

它给我一个错误,因为调用是模糊的,编译器不知道该调用哪个版本,因为两种方法都接受null作为第二个参数。

我如何在不改变其中一个方法名称的情况下克服这个问题?第一个方法永远不会有null


1
尝试这样调用:method("string", (string)null); 或 method("string", (object)null); - Mark
1
你使用的是哪个版本的.NET呢?因为这样就没有歧义了。规范在重载解析方面非常清晰明了。 - Hamlet Hakobyan
可能是重复的问题:当参数为空时如何解决歧义? - Chris
@HamletHakobyan .Net 4.0 - Nean Der Thal
1
正如@HamletHakobyan所说,你的示例不应导致歧义。这是因为每个“字符串”都是一个“对象”,但并非每个“对象”都是一个“字符串”,因此它不是对称的,在这种情况下,“最具体”的重载,即“Method(string, string)”被优先选择。你的实际场景可能是不同的。例如,如果重载是“Method(string, string)”和“Method(string, Uri)”,那么它将是有歧义的。 - Jeppe Stig Nielsen
显示剩余3条评论
2个回答

19
问题在于 `string` 和 `object` 都是可空的,因此 `null` 可能引用方法的任一重载。你需要将 null 值强制转换,尽管这听起来很愚蠢,以明确表示要调用哪个重载。
method("string", (string) null);
method("string", (object) null);

这基本上与您定义一个变量并传递该变量的类型相同:

string param1 = null;
object param2 = null;

method("string", param1); // will call the string overload
method("string", param2); // will call the object overload

param1param2都具有相同的值,null,但变量的类型不同,这就是编译器能够准确判断使用哪种重载的原因。上面使用显式转换的解决方案是一样的;它注释了一个类型到null值,然后用于推断正确的重载 - 只是没有声明一个变量而已。


谢谢。这是一种黑客方式吗?还是一种常见的解决问题的方法? - Nean Der Thal
不,这不是黑客攻击。这只是明确告诉编译器你想调用哪个重载版本,通过明确指定你所引用的版本。 - poke
这种方式至少可以避免R#警告,而不是我更喜欢的只使用string empty = null;等方式。 - Magus

3

您可以通过指定传递的 null 的类型来具体指定要调用的方法版本:

Method("string", null as string);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接