刚才读到Alan McGovern的[url=http://monotorrent.blogspot.com/2009/05/polymorphism-why-do-you-fail-me.html]一帖[/url],问为什么形式参数是ref A的地方不能把ref B作为实际参数传进去:
后面的回复很精辟的解答了这问题:如果把上面的Foo()实现成这样:
而同时允许传入ref b为参数的话,那就等于允许:
这显然就不行了——在类型安全的前提下,派生类引用无法指向基类的实例。
虽然是个小地方,乍一下没看出来的话还是会觉得很困惑,是吧?
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]再次讲解了这个问题
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]再次讲解了这个问题