0

2 つのクラスがあり、一方は他方から継承されます。基本クラスは MustInherit/abstract で、MustOverride/abstract プロパティを定義します。

基本クラスの初期化の一部として、abstract プロパティの値に基づいて変数を設定します。問題は、オーバーライドされたプロパティに割り当てられるべき値を継承クラスがパラメータとして受け入れることです。継承されたクラスはこのプロパティを設定しますが、基本クラスの初期化子を呼び出す前ではありません。

基本的には、基本クラスの一部を初期化してから、継承クラスがそのプロパティの一部を初期化できるようにし、基本クラスに戻ってさらに多くのプロパティの初期化を完了する必要があります。

プロパティを基本クラスの一部にしますが、継承クラスは厳密な型指定を使用しますが、基本クラスはインターフェイスのみを必要とします。

コード例:

MustInherit Class A
  MustOverride Property X As IExample

  Sub New()
    ' Do some stuff
    _privateY = X.Foo() ' NullReferenceException
  End Sub
End Class

Class B
  Inherits A

  Override Property X As IExample ' returns StrongX
  Property StrongX As ConcreteExample ' ConcreteExample implements IExample

  Sub New(x As ConcreteExample)
    MyBase.New(x)
    StrongX = x
  End Sub
End Class
4

3 に答える 3

3

コンストラクターで抽象メンバーを呼び出すべきではないのは、まさにこのためです。 http://msdn.microsoft.com/en-us/library/ms182331(v=vs.100).aspx

抽象クラスを制御できる場合は、基本クラスのコンストラクターを介して値を渡すことをお勧めします。

public abstract class A
{
    public A(IExample x)
    {
        // Do Stuff
        var _privateY = x.Foo();
    }
}

public class B : A
{
    public B(IExample x):base(x)    {}
}
于 2012-06-20T21:04:12.600 に答える
1

編集:申し訳ありませんが、私の答えはC#にあります:(

1 つのオプションは、サブクラスが実装できる仮想 (または抽象) 初期化メソッドを基本抽象クラスに呼び出すことです。

public abstract class A
{
    public abstract IExample X { get; set; }

    private object _privateY;

    protected A()
    {
        PreInit();

        PostInit();
    }

    protected abstract void PreInit();

    protected virtual void PostInit()
    {
        if (X == null)
            throw new InvalidOperationException("Must assign a value to X.");

        _privateY = X.Foo();
    }
}

次に、データBをオーバーライドPreInitして割り当てます。

public class B : A
{
    public override IExample X { get; set; }

    public B()
    {

    }

    protected override void PreInit()
    {
        X = new ConcreteExample();
    }
}
于 2012-06-20T21:08:21.170 に答える
0

を使用できますLazy<T>

public abstract class A
{
    private Lazy<IExample> _privateY = new Lazy(() => this.X.Foo());
}
于 2012-06-20T20:52:07.667 に答える