为什么不'裁判'和'去'的支持多态? [英] Why doesn't 'ref' and 'out' support polymorphism?

查看:133
本文介绍了为什么不'裁判'和'去'的支持多态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看看下面的:

class A {}

class B : A {}

class C
{
    C()
    {
        var b = new B();
        Foo(b);
        Foo2(ref b); // <= compile-time error: 
                     // "The 'ref' argument doesn't match the parameter type"
    }

    void Foo(A a) {}

    void Foo2(ref A a) {}  
}

为什么会出现上述编译时错误?这种情况既 REF 退出参数。

推荐答案

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

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

更新:我用这个答案作为此博客条目​​的基础:

UPDATE: I used this answer as the basis for this blog entry:

<一个href=\"http://blogs.msdn.com/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx\">Why做ref和out参数不允许类型变化?

有关此问题的详细解说,请参阅博客页面。感谢伟大的问题。

See the blog page for more commentary on this issue. Thanks for the great question.

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

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

让我们假设你有类动物哺乳动物爬虫长颈鹿,用显而易见子类之间的关系。

Let's suppose you have classes Animal, Mammal, Reptile, Giraffe, Turtle and Tiger, with the obvious subclassing relationships.

现在假设你有一个方法无效M(REF哺乳动物M) M 可以同时读取和写入 M

Now suppose you have a method void M(ref Mammal m). M can both read and write m.

您可以通过键入动物的变量 M

Can you pass a variable of type Animal to M?

没有。该变量可能包含一个,但 M 将假设它只包含哺乳动物。 A 不是哺乳动物

No. That variable could contain a Turtle, but M will assume that it contains only Mammals. A Turtle is not a Mammal.

结论1 REF 参数无法取得做大。 (还有更多的动物比哺乳动物,所以变量越来越大,是因为它可以包含更多的东西。)

Conclusion 1: ref parameters cannot be made "bigger". (There are more animals than mammals, so the variable is getting "bigger" because it can contain more things.)

您可以通过键入长颈鹿的变量 M

Can you pass a variable of type Giraffe to M?

没有。 M 可写入 M M 可能要写了 M 。现在,你已经把一个成一个变量,它实际上是类型长颈鹿

No. M can write to m, and M might want to write a Tiger into m. Now you've put a Tiger into a variable which is actually of type Giraffe.

2结论 REF 参数不能发的小

现在考虑 N(出哺乳动物N)

您可以通过键入长颈鹿的变量 N

Can you pass a variable of type Giraffe to N?

没有。 N 可写入 N N 可能要写了

No. N can write to n, and N might want to write a Tiger.

结论3 退出参数不能发的小

您可以通过键入动物的变量 N

Can you pass a variable of type Animal to N?

嗯。

那么,为什么不呢? N 无法从读取n ,它只能写,对不对?你写了一个来类型的变量动物和你所有的设置,对吧?

Well, why not? N cannot read from n, it can only write to it, right? You write a Tiger to a variable of type Animal and you're all set, right?

错误。该规则是不是 N 只能写 N

Wrong. The rule is not "N can only write to n".

的规则,简单地说:

1) N 有写 N N 正常返回。 (如 N 抛出,全盘皆输。)

1) N has to write to n before N returns normally. (If N throws, all bets are off.)

2) N 有写东西 N 才从读的东西ñ

这是允许此事件序列:


  • 定义一个字段 X 类型动物

  • X 退出参数 N

  • N 写入 N ,其中是 X 的别名。

  • 在另一个线程,有人写了一个 X

  • N 尝试读取的内容 N ,并发现了一个在它认为类型的变量哺乳动物

  • Declare a field x of type Animal.
  • Pass x as an out parameter to N.
  • N writes a Tiger into n, which is an alias for x.
  • On another thread, someone writes a Turtle into x.
  • N attempts to read the contents of n, and discovers a Turtle in what it thinks is a variable of type Mammal.

显然,我们想使非法。

Clearly we want to make that illegal.

结论4 退出参数无法取得更大的

Conclusion 4: out parameters cannot be made "larger".

最后结论无论 REF 也不退出参数可能会改变它们的类型。如果不这样做就是要打破可验证的类型安全。

Final conclusion: Neither ref nor out parameters may vary their types. To do otherwise is to break verifiable type safety.

如果在基本型理论的兴趣这些问题你考虑href=\"http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx\">我的一系列阅读

If these issues in basic type theory interest you, consider reading my series on how covariance and contravariance work in C# 4.0.

这篇关于为什么不'裁判'和'去'的支持多态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆