我有以下代码:
class Calculator
{
public int Sum(int x, int y)
{
return x + y;
}
public int Sum(out int x, out int y)
{
x = y = 10;
return x + y;
}
}
class Program
{
static void Main(string[] args)
{
int x = 10, y = 20;
Calculator calculator = new Calculator();
Console.WriteLine ( calculator.Sum ( x , y ) );
Console.WriteLine ( calculator.Sum ( out x , out y ) );
}
}
Run Code Online (Sandbox Code Playgroud)
尽管方法签名仅与out关键字不同,但此代码仍能正常运行.
但是以下代码不起作用:
class Calculator
{
public int Sum(ref int x, ref int y)
{
return x + y;
}
public int Sum(out int x, out int y)
{
x = y = 10;
return x + y;
}
}
class Program
{
static void Main(string[] args)
{
int x = 10, y = 20;
Calculator calculator = new Calculator();
Console.WriteLine ( calculator.Sum ( ref x , ref y ) );
Console.WriteLine ( calculator.Sum ( out x , out y ) );
}
}
Run Code Online (Sandbox Code Playgroud)
为什么这段代码不起作用?关键字如ref和out方法签名的一部分?
引用与其他答案略有不同,这是来自C#5规范的第3.6节,我发现它比"参考指南"更清晰,更精确:
虽然
out和ref参数修饰符被认为是签名的一部分,但在单一类型中声明的成员只能通过ref和out在签名上有所不同.如果在具有out修饰符的两个方法中的所有参数都更改为ref修饰符的情况下,如果两个成员在同一类型中声明具有相同签名的成员,则会发生编译时错误.用于签名匹配的其他目的(例如,隐藏或覆盖),ref并且out被认为是签名的一部分并且彼此不匹配.(此限制是为了允许C#程序轻松转换为在公共语言基础结构(CLI)上运行,这不提供定义仅在ref和中区别的方法的方法out.)
请注意,参数类型在dynamic这里略有相似 - 就CLR而言,这只是一个类型的参数object,所以这是无效的:
void InvalidOverload(object x) {}
void InvalidOverload(dynamic x) {}
Run Code Online (Sandbox Code Playgroud)
但是,在这种情况下,对于参数类型dynamic为覆盖参数类型为1 object或者反之亦然的方法,这是很好的- 重要的一点是它们等同于调用者,而对于out/ 不是这样ref.
| 归档时间: |
|
| 查看次数: |
6464 次 |
| 最近记录: |