`
RednaxelaFX
  • 浏览: 3052953 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

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

    博客分类:
  • C#
阅读更多
刚才读到Alan McGovern的一帖,问为什么形式参数是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,或许该提个建议让他们加点解释?

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

更新:
我 写道
C#语言规范的10.5.1.2小节讲解了reference parameter,不过并没有提到variance的问题……hmm,或许该提个建议让他们加点解释?

呜呜,发email给Eric Lippert跟他讨论这事,被精辟的回复拍回来了。
我眼残了,规范里的这句:
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 same type as the formal parameter.

我很自然的无视了“same”而把它看成了“compatible”……这个same就说明了类型的invariant性质,不允许多态。

更新2:
Eric在Why do ref and out parameters not allow type variation?再次讲解了这个问题
分享到:
评论
Global site tag (gtag.js) - Google Analytics