2017-04-20 7 views
-3

インスタンスコンストラクタが静的フィールドにアクセスするのはなぜですか?静的コンストラクタを介して静的フィールドを初期化し、間違ってインスタンスコンストラクタを使用して静的フィールドを初期化すると、2番目の初期化によって最初のものが上書きされます。インスタンスコンストラクタを使ってそれらをアクセス可能にする背景には何がありますか?コンストラクタは、静的メンバにアクセスしたいことができユースケースの一例として、(私のポイントを理解するには、以下の簡単なプログラムを見てください)どのようなロジックで、インスタンスコンストラクタは静的フィールドにアクセスする必要があります

using System; 

class Program 
{ 
    static void Main() 
    { 
     Circle C1 = new Circle(5); 
     Console.WriteLine("The area of the first circle is {0}", C1.CalculateArea()); 
    } 
} 

class Circle 
{ 
    public static float _Pi;       // Since the value of pi will not change according to circles, we have to make it static 
    int _Radius;          // This is an instance field, whose value is different for different instances of the class 

    static Circle()          // A static constructor initializes the static fields   
    { 
     Console.WriteLine("Static constructor executed"); 
     Circle._Pi = 3.14F; 
    } 
    public Circle(int Radius)       // An instance constructor initializes the instance fields 
    { 
     Console.WriteLine("Instance constructor executed"); 
     this._Radius = Radius; 
     Circle._Pi = 2.12F;        // This again initializes the value of the pi to a different value as given by the static constructor 
    } 
    public float CalculateArea() 
    { 
     return this._Radius*this._Radius*Circle._Pi; 
    } 
} 
+1

は、書き込みを不可能にする 'const'を使用します。 –

+0

ダニエルそれは私の質問のポイントではありません。静的フィールドを書き込み不可能にする方法は他にもあります。私の懸念は、なぜこの機能が提供されているのですか?どのような例のように、インスタンスコンストラクタは静的フィールドを使用する必要がありますか? – TotalGadha

答えて

0

静的フィールドは、Aのインスタンスのカウンタが含まれているときクラス。クラスメンバが静的でないフィールドで取得し、保持し、このカウンタを静的に増やしたい場合があります。将来はいつでもインスタンスには独自の一意識別子があります。

例:

public class Employee { 
     static int NextEmployeeId; // a counter across all employees 

     public int EmployeeId; // this instance's employee id 
     public string Name;  // this instance's name. 

     static Employee() { 
      Employee.NextEmployeeId = 1; // first employee gets 1. 
     } 

     public Employee(string Name) { 
      this.Name = Name; 
      this.EmployeeId = Employee.NextEmployeeId++; // take an id and increment for the next employee 
     } 

} 
+0

あなたはあなたの答えを例で説明できますか?私があなたが説明しようとしているのと同じことを理解したことを確かめるために、P – TotalGadha

0

静的フィールドでも、コンストラクタから、あるいはメイン/他のクラスから、どこからでもアクセス可能です。目的は、アプリケーション全体に対して静的なプロパティ/フィールドのシングルトンを1つだけ持つことです。

public class AClass() 
{ 
    public static float staticField; 
    public float field; 
    public AClass() 
    { 
     staticField = 5; 
     field = 6; 
    } 
    static AClass() 
    { 
     staticField = 7; 
    } 
} 

public int Main() 
{ 
    float initially = AClass.staticField; // initially this staticField is 7. 
    AClass aclass = new AClass(); // instantiating AClass 
    float localfield = aclass.field; // this field does not affect anyone. It is 6 
    float newStaticField = AClass.staticField; // Due to previous instantiation, the value is now 5. 

} 

あなたの例では悪いと私は同意します。どうして?なぜPiの値を変更するのかは、既に決定され固定されているため、コンストラクタ内のPiの値を変更する理由はありません。

クラスを設計し、最初に静的フィールドを使用する理由を知る必要があるかもしれません。ここでは、静的フィールドを正しく持つクラスの例を示します(例えば、キーが隠蔽されるべきであるなど)。

public class NewEncryptionClass() 
{ 
     public static string Key; 
     public NewEncryptionClass() 
     { 

     } 
     public NewEncryptionClass(string newKey) 
     { 
      Key = newKey; // store the key and keep it forever 
     } 
     static NewEncryptionClass() 
     { 
      Key = "key1"; // initially key is "key1" 
     } 
     public string Encrypt(string str) 
     { 
      string result = string.Empty; 
      result = "adlasdjalskd" + Key + "ajlajfalkjfa" + str; // do the Encryption, I just made up 
      return result 
     } 
} 

ここでは、NewEncryptionClassをインスタンス化した場合、そのキーを保存して、次回の暗号化を実行する際に常に最新のキーを使用するようにします。例の場合:私はない、このクラスの設計が間違っている場合は、永遠に最新のキーを維持したいとあなたがあなたの目的のためにそれを書き換える必要がある場合

public int Main() 
{ 
    string initialkey = NewEncryptionClass.Key; 
    string result1 = new EncryptionClass().Encrypt("encryptThis"); // using key1 

    // let's change the key 
    string result2 = new EncryptionClass("key2").Encrypt("encryptThat"); // using key2 
    string result3 = new EncryptionClass().Encrypt("encryptOther"); // still using key2 


} 

これは、もちろんです。

関連する問題