2017-04-20 31 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 


} 

这是当然的,如果我想保持最新的关键永远,如果没有,那么这个类的设计是错误的,你需要重写一遍你的目的。

相关问题