2017-09-03 11 views
-1

C#では実際に動作するこのコンパイルと実行はできますが、正しく動作しません。C#の子クラスの親クラスの配列メンバーを初期化する

public abstract class Foo 
{ 
    public int[] a; 
} 

public class Bar : Foo 
{ 
    public int[] a = new int[123]; 
} 

これを使用する必要がありますか(うまく動作しますが、上記のコードと同じようには見えません)。

public abstract class Foo 
{ 
    public int[] a; 

    public void Init(int size) 
    { 
     a = new int[size]; 
    } 
} 

public class Bar : Foo 
{ 
    public Bar() 
    { 
     Init(123); 
    } 
} 
+2

"達成するためには何をしますか?最初のクラスは基本クラスの 'a'をシャドーイングしています。これはかなり混乱することがあります。コンストラクタを使用することは通常、再宣言よりも好ましいが、意図どおりに意図に依存する。 – dlatikay

+0

これを行う必要がありますpublic int [] a = new int [123];基本抽象クラスのいずれか、または子クラスがそれを実装することを期待する場合は、それをabastractとしてマークする必要があります。public abstract int [] a; – Isma

+0

バーでは、_a = new int [123]; _を抽象クラスによって継承されたものを再宣言することなく書き出します。 – Steve

答えて

2

Bar.a皮継承ベース部材(Foo.a)。これを正しく行うには最初にとすると、ベースメンバーをフィールドからプロパティに変更する必要があります。abstractとして宣言し、次に派生クラスにoverrideと宣言してください。

public abstract class Foo 
{ 
    public abstract int[] a { get; set; } 
} 

public class Bar : Foo 
{ 
    public override int[] a { get; set; } 
} 

それともだけしたい場合は、子クラスは、このようなあなたの派生クラスで配列サイズ使用constructor設定している:あなたのコメントに基づいて

public abstract class Foo 
{ 
    public int[] a; 
} 

public class Bar : Foo 
{ 
    public Bar() 
    { 
     a = new int[123]; 
    } 
} 
2

を上記:

このような何か

目的は、子クラスに配列サイズを設定させることです。

それは、コンストラクタと呼ばれているもの、あなたが探しているように聞こえます。これを使用して、オブジェクトのインスタンスを作成するために必要な値を定義し、それらの値を使用してオブジェクトを構築します。コンストラクタに値を供給する

public abstract class Foo 
{ 
    public int[] a; 

    public Foo(int size) 
    { 
     a = new int[size]; 
    } 
} 

だから今1人のニーズ

あなたの基底クラスは、このような何かを値を必要とします。子クラスは、コンストラクタチェーンを使用して簡単に独自のコンストラクタから値を提供できます。

public class Bar : Foo 
{ 
    public Bar(int size) : base(size) { } 
} 
+0

コンストラクタチェインについてはわかりませんでしたが、良い解決策のようです。 – Thorham

+1

フィールド 'a'は' readonly'のように感じるでしょう。 –

+0

@Jeppe Stig Nielsen - 実際のプロジェクトでは変更できないのでできません。フィールドはPRNG状態を保持し、必要に応じて再シードすることが可能でなければならず、PRNGの状態を保存および復元することも可能でなければならない。 – Thorham

関連する問題