看到一个关于ref参数与多态的问题,记一下

本文探讨了C#中为何不允许将派生类引用作为基类引用的ref参数传递,通过具体示例解释了这一限制背后的原因,并引用了C#语言规范的相关规定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚才读到Alan McGovern的[url=http://monotorrent.blogspot.com/2009/05/polymorphism-why-do-you-fail-me.html]一帖[/url],问为什么形式参数是ref A的地方不能把ref B作为实际参数传进去:
class A { }
class B : A { }

// ...
public void Foo( ref A a ) {
// ...
}

public void Bar( ) {
B b = new B( );
Foo( ref b ); // error
}

后面的回复很精辟的解答了这问题:如果把上面的Foo()实现成这样:
public void Foo( ref A a ) {
a = new A( );
}

而同时允许传入ref b为参数的话,那就等于允许:
B b = new A();

这显然就不行了——在类型安全的前提下,派生类引用无法指向基类的实例。

虽然是个小地方,乍一下没看出来的话还是会觉得很困惑,是吧?
C#语言规范的10.5.1.2小节讲解了reference parameter,不过并没有提到variance的问题……hmm,或许该提个建议让他们加点解释?

==========================================================

更新:
[quote="我"]C#语言规范的10.5.1.2小节讲解了reference parameter,不过并没有提到variance的问题……hmm,或许该提个建议让他们加点解释?[/quote]
呜呜,发email给Eric Lippert跟他讨论这事,被精辟的回复拍回来了。
我眼残了,规范里的这句:
[quote="C# Language Specification 10.6.1.2"]When a formal parameter is a reference parameter, the corresponding argument in a method invocation must consist of the keyword ref followed by a variable-reference of the [color=red]same type[/color] as the formal parameter.[/quote]
我很自然的无视了“same”而把它看成了“compatible”……这个same就说明了类型的invariant性质,不允许多态。

更新2:
Eric在[url=http://blogs.msdn.com/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx]Why do ref and out parameters not allow type variation?[/url]再次讲解了这个问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值