8

次のような基本クラス「親」があります。

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Parent
    {
        private int parentVirtualInt = -1;
        public virtual int VirtualProperty
        {
            get
            {
                return parentVirtualInt;
            }
            set
            {
                if(parentVirtualInt != value)
                {
                    parentVirtualInt = value;
                }
            }
        }
    }
}

そして、このような子クラス:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Child : Parent
    {
        public override int VirtualProperty
        {
            get
            {
                if(base.VirtualProperty > 0)
                {
                    throw new ApplicationException("Dummy Ex");
                }
                return base.VirtualProperty;
            }
            set
            {
                if(base.VirtualProperty != value)
                {
                    base.VirtualProperty = value;
                }
            }
        }
    }
}

Child の getter が Parent の getter を呼び出していることに注意してください (または、少なくともこれは私が意図していることです)。

ここで、"Child" クラスをインスタンス化して使用し、その VirtualProperty に値 (4 としましょう) を割り当ててから、プロパティを再度読み取ります。

Child c = new Child();
c.VirtualProperty = 4;
Console.Out.WriteLine("Child.VirtualProperty: " + c.VirtualProperty);

これを実行すると、明らかに「Dummy Ex」という ApplicationException が発生します。しかし、行にブレークポイントを設定すると

if(base.VirtualProperty > 0)

Child で、例外がスローされる前にbase.VirtualProperty(その上にマウスを置いて)の値を確認します(私は (d) と仮定します)、既に例外を取得しています。このことから、「チャイルドゲッターは自分自身を呼び出す」のステートメントが伝えられます。すこし。base.VirtualProperty

私が達成したいのは、parentVirutalInt(Parent 内の) の定義を protectedに変更し、base.parentVirtualInt代わりに Child の Getter で使用した場合と同じ動作ですbase.VirtualProperty。なぜこれが機能しないのか、まだわかりません。誰でもこれに光を当てることができますか?オーバーライドされたプロパティの動作は、オーバーライドされたメソッドとは異なると思いますか?

ちなみに、私は自分が制御できないクラスをサブクラス化することと非常によく似たことを行っています(これが、私の「回避策」がオプションではない主な理由です)。

敬具

4

1 に答える 1

8

これは (ほぼ間違いなく) デバッガーのバグです。このフィードバック記事に投票することができます。これを修正するのは簡単ではありません。確かに、プロパティ ゲッターの v-table スロットが派生クラスで置き換えられているため、デバッガーはベース プロパティ ゲッター メソッドのアドレスにすぐにアクセスできません。

考えられる回避策の 1 つは、最初にベース値をローカル変数に格納して、その値を検査できるようにすることです。それによってゲッターが遅くなることはありません。

于 2010-03-16T15:58:50.447 に答える