C#中静态成员和常量之间的真正区别是什么?

时间:2017-09-30 13:26:19

标签: c#

我正在学习C#,现在我正在尝试理解静态成员和常量。这是声明常量的最佳方法吗? 这样吗?

class Myclass
{
    public const double G=9.8;
}

或者

   class Myclass
    {
        private static double G{get;set;}
        static MyClass()
        {
            G=9.8;
        }
    }

我已经问过这个问题了,因为我使用相同代码访问membre的两种方式:

Console.WriteLine(Myclass.G);

4 个答案:

答案 0 :(得分:1)

<强>常数

  

常量字段在代码中声明时定义   片段,因为一旦定义它们就无法修改。通过   默认常量是静态的,因此您无法从中定义静态   你的身边。

     

此时还必须为它们分配值   否则它会在编译过程中出错   程序片段。这就是为什么它也被称为编译时常量。

<强>解释

考虑ff。代码:

void Sum(int j)  
{  
  const int i = 9, k = 2;  
  const int A = i + k;  
} 

这将产生11的结果,因为我们已经在声明的初始阶段声明了它,所以没有显示任何错误。

但是如何:

void Sum(int j)  
{  
   const int i = 9, k = 2;  
  //const int A = i + k;  
   Const int B = i + j;  
} 

此代码段将带您进入编译时错误,因为没有初始化,因为它是在运行时进行评估的。

要记住的要点

  • 编译时常数
  • 无法声明为静态
  • 无法修改或更改
  • 可以是任何类型的访问修饰符
  • 本地范围
  • 需要初始化
  • 在声明时宣布

静态

  

static关键字用于声明静态成员。如果我们是   将一个类声明为静态类,然后在本例中将所有类声明   成员也必须是静态的。 static关键字可以有效使用   与类,字段,运算符,事件,方法等   有效。

考虑ff。代码:

class ReadOnly  
{  
    static int i = 11;  
    public static void disp()  
    {  
        Console.WriteLine(i);
    }  
}

<强>解释

此代码不会显示错误并产生结果(11),因为我们在声明时将其值声明为静态。所以我们可以根据我们在程序中的使用来访问它。

但是这个怎么样:

class ReadOnly  
{  
    int i = 9;  
    public static void disp()  
    {  
        Console.WriteLine(i);  
    }  
}

上面的这个代码段会显示错误,因为我们没有为静态声明一个值,我们正试图在方法中访问它。我们做不到。

要记住的要点:

  • 不能与索引器一起使用
  • 也适用于构造函数
  • 默认为私有
  • 可以参数化或公开
  • 如果它应用于某个类,那么所有类成员都需要是静态的

您可以在此处详细了解上述说明:constant vs readonly vs static

static方法的补充说明。

考虑ff。代码:

public class SomeClass {
    public string SomeMethod() {
      return "Hello, World.";
    }
}

如果要访问SomeMethod的{​​{1}},则需要先SomeClass实例化:

SomeClass

与静态方法相比:

var some = new SomeClass();
string result = some.SomeClass(); //this will set result as "Hello, World."

访问public class SomeClass { public static string SomeMethod() { return "Hello, World."; } } 时,您无需实例化SomeMethod。您可以通过以下方式直接访问它:

SomeClass

答案 1 :(得分:1)

  

哪个是声明常量的最佳方式?

它不是最好的,只有 const double G = 9.8;

  

或(...)static double G { get; set; }

多数民众赞成不变!常量意味着常数1是一个常数,'c'是一个常数,PI是一个常数......它们代表 don&#39的值; t改变 永远! 。你的G的第二次实现可以改变,因此它不是常数。

另外,重要的是你注意到常量在编译时已知,在运行时不需要评估。

这就是为什么任何引用类型const(期望string通过字符串文字具有特定编译器支持)的原因只能初始化为null,任何其他选项都需要在运行时进行评估。

这也是为什么只有一组有限的值类型也可以声明为const的原因。所有这些都是框架中的现有类型,并且令人惊讶,它们都具有编译器文字常量支持:1'c'9.8或{ {1}}但不是0.25M(编译器在运行时之前如何知道值?)。

  

你没有提出的另一个有趣问题是:01/01/2017怎么办?

您可以将static readonly视为&#34;穷人&#34; static readonly。它经常被用来规避const关于允许哪些类型和初始化值的限制。

几乎与常数相同,但有一些重要和决定性的差异:

  1. 可以改变;虽然它是const,但您可以在声明类型的静态构造函数中更改它的值。初始化后readonly永远不会改变。
  2. 运行时进行评估,而不是将时间编译为真const
  3. 任何类型都可以声明为const并初始化为任何有效值,就像使用任何常规字段一样。
  4. 作为一个挑剔的旁注,你不应该使static readonly成为常数;)。它改变了,而且相当多。厄瓜多尔的G与北极的G不同。

答案 2 :(得分:0)

  

const变量在定义时分配值。

它们在编译时可用。您甚至可以在编译时使用编译时可评估表达式。但是,一旦将值赋给const变量,就不能在任何其他时间更改它。

  

使用静态字段意味着该值对于应用程序的每个用户都将保持相同,但是可以通过任何类中的代码更改此值,并且该值将针对应用程序的每个用户进行更改。

不要将static用于常量,只使用const。 const默认是静态的,你不能使用static关键字。

检查

void Main()
{
 // You will not be able to change value for const variable.
 Console.WriteLine(Myclass.G);

  // You will be able to change value for static variable, 
 // and this change will impact all users of the application.
 //  For every user, this field will store value of 10 now. 
 // That will not be required or desired code behavior.
 Myclass1.G = 10;
 Console.WriteLine(Myclass1.G);
}

// Normal class with const field 
class Myclass
{
    public const double G=9.8;
}

 //static class with static constructor
 static class Myclass1
    {
        public static double G{get;set;}
        static Myclass1()
        {
            G=9.8;
        }
    }

Read More

答案 3 :(得分:0)

这里你谈论的是两个不同的东西,这是他们从MSDN中的定义:

1- static modifier :声明一个静态成员,它属于该类型本身而不是特定对象。 static修饰符可以与类,字段,方法,属性,运算符,事件和构造函数一起使用,但不能与索引器,终结器或类以外的类型一起使用。

2- const关键字:声明常量字段或常量局部。常量字段和局部变量不是变量,可能不会被修改。常量可以是数字,布尔值,字符串或空引用。不要创建常量来表示您希望随时更改的信息。

因此,为一个Class定义了一个静态成员(对于它的所有实例,这就是你可以直接从类的名称访问它的原因),但是可以修改它。类的const字段无法修改。