我有一个带有重载格式方法的类。
class FormatStuff
{
public static string Format(object arg)
=> HandleObjectStuff();
public static string Format(IEnumerable<object> args)
=> HandleListStuff();
}
现在,当我打电话
FormatStuff.Format(null);
我在IEnumerable参数的第二次重载中结束。 但就我而言,我在这样的函数中调用该方法:
public static string DoStuff(IEnumerable<int> intnumerable)
{
StringBuilder sb = new StringBuilder();
sb.Append(FormatStuff.FormatFunctionParameter(intnumerable));
return sb.ToString();
}
当我将此功能称为
时DoStuff(null);
我在单个对象参数的第一次重载中结束,即使在两种情况下都将null作为参数传递。
为什么这和我该怎么做才能在与DoStuff参数类型相匹配的第二个重载中结束?
修改
该问题已标记为this一个可能的副本。我认为情况并非完全如此,因为帮助我理解我的问题的重点是,IEnumerable<int>
不是IEnumerable<object>
。
一般来说,这意味着,不能指望任何类型的IEnumerable都是IEnumerable对象,我不知道。
这个结论没有在上述帖子中得出。
答案 0 :(得分:2)
在编译时为每个调用表达式静态修复哪个调用(绑定)重载(除非在编译时使用类型dynamic
)。只是因为用于参数的表达式恰好在程序运行时计算为另一种类型,所以重载不会神奇地改变。
示例:
FormatStuff.Format(null);
编译时类型不存在(null),但由于存在从null
字面到object
的隐式转换以及从null
到{{1的隐式转换同样,两个重载都是候选者。在这种情况下,首选IEnumerable<object>
的重载是首选,因为它更具体。
IEnumerable<object>
在这种情况下,表达式的编译时类型为FormatStuff.Format((object)null);
,因此只应用一个重载,并使用它。
object
在上面的例子中,你传递的编译时类型是IEnumerable<int> intnumerable
// ...
FormatStuff.Format(intnumerable);
。这里IEnumerable<int>
是值类型。编译时int
不是IEnumerable<int>
。 这是在编译时修复的; 在运行时IEnumerable<object>
恰好是intnumerable
并不重要,如果非空,则无关紧要实际类型(实现null
的一些具体类或结构)是在运行时。
IEnumerable<int>
最后,在这种情况下,由于IEnumerable<string> strEnumerable
// ...
FormatStuff.Format(strEnumerable);
是引用类型,string
的编译时协方差适用。因此,IEnumerable<out T>
是IEnumerable<string>
。因此,两种过载均适用,并且最具体的一种是优选的。
答案 1 :(得分:0)
要实现您的目标,您的方法必须能够区分两个方法调用。
当您通过null
时,Format()
方法无法知道您的null是object
还是IEnumerable<object>
,因为它们都是object类型。
要解决您的问题,您可以执行以下操作之一:
Format(IEnumerable<int> args)
OR