选择不同的重载方法,具体取决于使用空参数调用它的位置
Different overload method is chosen, depending from where it's called with a null parameter
我有一个 class 带有重载的 Format 方法。
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.Format(intnumerable));
return sb.ToString();
}
当我像这样调用这个函数时
DoStuff(null);
我在第一个重载中以单个对象参数结束,即使在这两种情况下都将 null 作为参数传递。
为什么会这样,我该怎么做才能结束与 DoStuff 参数类型相匹配的第二次重载?
编辑:
该问题已被标记为可能与 this 个问题重复。我不认为情况完全如此,因为帮助我理解我的问题的重点是 IEnumerable<int>
不是 IEnumerable<object>
。
一般来说,这意味着,不能期望任何类型的 IEnumerable 是对象的 IEnumerable,我不知道。
上述post.
中并没有得出这个结论
要实现您想要的效果,您的方法必须能够区分 两个方法调用。
当您传递 null
时,Format()
方法不知道您的 null 是 object
还是 IEnumerable<object>
,因为两者都是对象类型。
要解决您的问题,您可以执行以下操作之一:
- 1 将第二种方法改为
Format(IEnumerable<int> args)
或
- 2 通过添加可选参数更改方法的类型签名。以this为例
在 compile-time 处每个调用表达式要调用(绑定)的重载是静态固定的(除非您在 compile-time 处使用类型 dynamic
)。仅仅因为您用于参数的表达式在程序运行时恰好求值为另一种类型,所以重载不会神奇地改变。
示例:
FormatStuff.Format(null);
compile-time 类型不存在(null),但由于存在从 null
文字到 object
的隐式转换以及从 null
的隐式转换IEnumerable<object>
,两个重载都是候选者。在那种情况下,使用 IEnumerable<object>
的重载是首选,因为它更具体。
FormatStuff.Format((object)null);
在这种情况下,表达式的 compile-time 类型是 object
,因此只有一个重载适用,并且使用了它。
IEnumerable<int> intnumerable
// ...
FormatStuff.Format(intnumerable);
在上述情况下,您传递的 compile-time 类型是 IEnumerable<int>
。这里 int
是一个 value-type。 IEnumerable<int>
不是 compile-time 处的 IEnumerable<object>
。 这个固定在compile-time;不管intnumerable
是否恰好在run-time是null
,如果non-null,在 run-time.
处的实际类型(一些具体的 class 或实现 IEnumerable<int>
的结构)是什么并不重要
IEnumerable<string> strEnumerable
// ...
FormatStuff.Format(strEnumerable);
最后,在这种情况下,由于 string
是引用类型,因此 IEnumerable<out T>
的 compile-time 协方差适用。所以 IEnumerable<string>
是 和 IEnumerable<object>
。因此,两种重载都适用,最具体的一种是首选。
我有一个 class 带有重载的 Format 方法。
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.Format(intnumerable));
return sb.ToString();
}
当我像这样调用这个函数时
DoStuff(null);
我在第一个重载中以单个对象参数结束,即使在这两种情况下都将 null 作为参数传递。
为什么会这样,我该怎么做才能结束与 DoStuff 参数类型相匹配的第二次重载?
编辑:
该问题已被标记为可能与 this 个问题重复。我不认为情况完全如此,因为帮助我理解我的问题的重点是 IEnumerable<int>
不是 IEnumerable<object>
。
一般来说,这意味着,不能期望任何类型的 IEnumerable 是对象的 IEnumerable,我不知道。
上述post.
要实现您想要的效果,您的方法必须能够区分 两个方法调用。
当您传递 null
时,Format()
方法不知道您的 null 是 object
还是 IEnumerable<object>
,因为两者都是对象类型。
要解决您的问题,您可以执行以下操作之一:
- 1 将第二种方法改为
Format(IEnumerable<int> args)
或
- 2 通过添加可选参数更改方法的类型签名。以this为例
在 compile-time 处每个调用表达式要调用(绑定)的重载是静态固定的(除非您在 compile-time 处使用类型 dynamic
)。仅仅因为您用于参数的表达式在程序运行时恰好求值为另一种类型,所以重载不会神奇地改变。
示例:
FormatStuff.Format(null);
compile-time 类型不存在(null),但由于存在从 null
文字到 object
的隐式转换以及从 null
的隐式转换IEnumerable<object>
,两个重载都是候选者。在那种情况下,使用 IEnumerable<object>
的重载是首选,因为它更具体。
FormatStuff.Format((object)null);
在这种情况下,表达式的 compile-time 类型是 object
,因此只有一个重载适用,并且使用了它。
IEnumerable<int> intnumerable
// ...
FormatStuff.Format(intnumerable);
在上述情况下,您传递的 compile-time 类型是 IEnumerable<int>
。这里 int
是一个 value-type。 IEnumerable<int>
不是 compile-time 处的 IEnumerable<object>
。 这个固定在compile-time;不管intnumerable
是否恰好在run-time是null
,如果non-null,在 run-time.
IEnumerable<int>
的结构)是什么并不重要
IEnumerable<string> strEnumerable
// ...
FormatStuff.Format(strEnumerable);
最后,在这种情况下,由于 string
是引用类型,因此 IEnumerable<out T>
的 compile-time 协方差适用。所以 IEnumerable<string>
是 和 IEnumerable<object>
。因此,两种重载都适用,最具体的一种是首选。