2017-04-20 29 views
-3

我想知道爲什麼實例構造函數可以訪問靜態字段?如果我通過靜態構造函數初始化靜態字段,並通過錯誤再次通過實例構造函數初始化靜態字段,則第二次初始化會覆蓋第一個。通過實例構造函數使它們可訪問的背後是什麼? (請看看簡單的程序下面來了解我的觀點)通過什麼邏輯,實例構造函數可以訪問靜態字段

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

作爲使用情況下構造可能希望獲得靜態成員是一個例子,當一個靜態字段包含實例的計數器類。你可能想讓一個類成員獲得,保留(在一個非靜態字段中),並增加這個靜態的計數器。在將來的任何時候,該實例都將擁有自己的唯一標識符。

實施例:

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

靜態字段是來自世界各地的訪問,甚至是從構造,或甚至從主/其他類。目的是爲了讓整個應用程序只有一個靜態屬性/字段單例。

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的值。

您可能需要知道如何設計課堂並瞭解您爲什麼希望將靜態字段放在首位。下面是一個類的例子,它有正確的靜態字段(例如,因爲Key應該被隱藏起來,這只是爲了向你展示靜態字段是如何有用和可以的):

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 


} 

這是當然的,如果我想保持最新的關鍵永遠,如果沒有,那麼這個類的設計是錯誤的,你需要重寫一遍你的目的。

相關問題