-8

私は2つのクラスを持っています:

public class Class1
{
   private string Name1;
   public Class1()
   {
      //How to get Name2 of the derived class?
   }  
}

public class Class2 : Class1
{
   private string Name2 = "asd"; 
   public Class2(){}
}

Name2基本コンストラクターで派生クラスを取得する方法は?

public class Class1
{
   private string Name1;
   public Class1()
   {
       class2 xxx = this as class2      
       if (class2 != null) 
          this.Name1 = xxx.Name2;
   }  
}

"this as class2" - null ではない

この例は正しいです。唯一のことは、派生クラスがClass2またはclass3またはclass4であることを知らないことです....ユニバーサルコードが必要です

4

5 に答える 5

2

それを行うことはできません (さらに重要なことに、行うべきではありません)。基本クラスのコンストラクターにいるとき、サブクラス部分はまだ初期化されていないため、サブクラスのメンバーにアクセスする方法はありません。単純に、それらはまだ存在していません。

もう 1 つの問題は、定義のレベルであっても、属性Name2がサブクラスにまったく存在しない可能性があるClass3ことです。Class1Name3Name2

これはすべて、カプセル化の解除などの「取るに足らない」問題には触れていません:Name2はプライベート メンバーであり、将来の の実装で削除される可能性がありますClass2

サブクラスがコンストラクターでスーパークラスに通信する唯一の方法は、パラメーターを渡すことです。これはうまくいきます:

public class Class1 {
    private string Name1;
    public Class1(string subclassName2)
    {
        // Subclass has passed its Name2 here
    }  
}

public class Class2: class1 {
    private string Name2; 
    public Class2(string myName) : base(myName) {
        Name2 = myName;
    }
}
于 2013-03-10T12:50:51.067 に答える
1

基本クラスコードから派生クラスのコードにアクセスできますが、実際には派生クラスオブジェクトであるオブジェクト内からのみ、関連するメソッドが仮想メソッドである場合に限ります。

それ自体が基本クラスのインスタンスであるオブジェクトがある場合、そのインスタンス内からは、基本クラスから派生したクラスコードを表示できません。

public class Baseclass{

  public void Foo()
  {
      Bar();
  }
  public virtual void Bar()
  {
     print("I'm a BaseClass");}}


public classs Derived: BaseClass{

  public override void Bar()
  {
     print("I'm a Derived Class");}}


Main()

   var b = new BaseClass();
   x.Foo()  // prints "I'm a BaseClass" 
   // This Foo() calls Bar() in base class  
    var d = new Derived();
   d.Foo()  // prints "I'm a Derived Class" 
   // in above, the code for Foo() (in BaseClass)
   //  is accessing Bar() in derived class      
于 2013-03-10T13:13:27.247 に答える
0

あなたはそれをすることはできません。これは、オブジェクト指向アプローチプログラミングの基本ルールに厳密に違反しています。

の各インスタンスにClass2Name2プロパティがあります。ただし、のオブジェクトのインスタンスについては同じことを保証することはできませんClass1

于 2013-03-10T12:57:37.237 に答える
0

派生クラスをインスタンス化するときに、基本クラスのコンストラクターが最初に呼び出されて基本クラスが初期化され、次に派生クラスが初期化されるため、できなかったと思います。基本クラスのコンストラクター内では、派生クラスのメンバーは利用できないため、アクセスする方法がありません。その時。

于 2013-03-10T12:49:43.913 に答える
0

何を達成しようとしているのかは明確ではありません。次のことは可能ですが、良い習慣ではないと思います。

    interface IHasName2
    {
        string Name2 { get; }
    }
    class Class1
    {
        string Name1;

        public Class1()
        {
            var withName2 = this as IHasName2;
            if (withName2 != null)
            {
                Name1 = withName2.Name2;
            }
        }
    }

から派生したクラスは、必要に応じてClass1実装IHasName2できます。

しかし、abstract派生クラスがName2. 次のようになります。

    abstract class Class1
    {
        string Name1;

        // instance property required to be implemented by deriving classes
        protected abstract string Name2 { get; }

        // instance constructor
        protected Class1()
        {
            // 'Name2' can be read already here (dangerous?)
            Name1 = Name2;
        }
    }

最後に、dasblinkenlight によって提案された単純な解決策を検討して、インスタンス コンストラクターが名前のパラメーターをClass1受け取るようにします。string派生クラスは、基本クラスのコンストラクターを「チェーン」するときに、その名前パラメーターを指定する必要があります。

于 2013-03-10T14:11:50.893 に答える