通过什么逻辑,实例构造函数是否可以访问静态字段

时间:2017-04-20 01:14:46

标签: c# constructor

我想知道为什么实例构造函数可以访问静态字段?如果我通过静态构造函数初始化静态字段,并且错误地再次通过实例构造函数初始化它们,那么第二个初始化将覆盖第一个。通过实例构造函数可以访问它们的想法是什么? (请查看下面的简单程序以了解我的观点)

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;
    }
}

2 个答案:

答案 0 :(得分: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
      }

}

答案 1 :(得分:0)

静态字段可以从任何地方访问,甚至可以从构造函数,甚至从Main / other类访问。目的是整个应用程序只有一个静态属性/字段单例。

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


}

这当然是如果我想永远保留最新的密钥,如果没有,那么这个类设计是错误的,你需要为你的目的重写它。