SWB*_*SWB 34 c# null overloading
假设我有两个C#方法的重载版本:
void Method( TypeA a ) { }
void Method( TypeB b ) { }
Run Code Online (Sandbox Code Playgroud)
我用以下方法调用该方法:
Method( null );
Run Code Online (Sandbox Code Playgroud)
调用该方法的哪个重载?我该怎么做才能确保调用特定的重载?
Jon*_*eet 71
这取决于TypeA和TypeB.
null,TypeB因为它是值类型但是TypeA引用类型),那么将调用适用的那个.TypeA和之间的关系TypeB.
TypeA,TypeB但没有隐式转换TypeB,TypeA那么TypeA将使用重载使用.TypeB,TypeA但没有隐式转换TypeA,TypeB那么TypeB将使用重载使用.有关详细规则,请参阅C#3.0规范的7.4.3.4节.
这是一个不模糊的例子.这里TypeB派生的TypeA,这意味着有一个从隐式转换TypeB到TypeA,而不是相反.因此使用过载TypeB:
using System;
class TypeA {}
class TypeB : TypeA {}
class Program
{
static void Foo(TypeA x)
{
Console.WriteLine("Foo(TypeA)");
}
static void Foo(TypeB x)
{
Console.WriteLine("Foo(TypeB)");
}
static void Main()
{
Foo(null); // Prints Foo(TypeB)
}
}
Run Code Online (Sandbox Code Playgroud)
一般来说,即使面对其他模糊的调用,为了确保使用特定的重载,只需转换:
Foo((TypeA) null);
Run Code Online (Sandbox Code Playgroud)
要么
Foo((TypeB) null);
Run Code Online (Sandbox Code Playgroud)
请注意,如果这涉及声明类中的继承(即一个类重载由其基类声明的方法),那么您将遇到另一个问题,并且需要转换方法的目标而不是参数.
Jon Skeet给出了一个全面的答案,但从设计的角度来看,你不应该依赖于编译器规范的角落情况.如果没有别的,如果你在写它之前必须查看它的作用,下一个尝试阅读它的人也不会知道它做了什么.这是不可维护的.
为方便起见,重载是有的,并且具有相同名称的两个不同重载应该做同样的事情.如果这两种方法做了不同的事情,请重命名其中一种或两种.
对于重载方法而言,更常见的是具有不同数量的参数的变体,以及具有较少参数的过载以提供合理的默认值.
例如string ToString(string format, System.IFormatProvider provider),参数最多,
string ToString(System.IFormatProvider provider)提供默认格式,并
string ToString()提供默认格式和提供者,
小智 5
Jon Skeet 已经回答了默认选择哪个重载,但是如果您想确保调用特定的重载,通常使用命名参数比强制转换更好。
如果你有:
void Method( TypeA a ) { }
void Method( TypeB b ) { }
Run Code Online (Sandbox Code Playgroud)
你可以打电话Method(a: null);或Method(b: null);
| 归档时间: |
|
| 查看次数: |
6360 次 |
| 最近记录: |