34

変数を持つことと C# で変数を持つことの間に違いはありprivate constますか(コンパイル時の式を割り当てる必要があることを除いて)?private static readonlyconst

どちらもプライベートなので、他のライブラリとのリンクはありません。それで何か違いはありますか?たとえば、パフォーマンスの違いを生むことはできますか? インターンストリング?似たようなものはありますか?

4

9 に答える 9

34

const はコンパイル時に存在するため、属性で const を使用できます。.cctor構成などから初期化できるため、静的読み取り専用変数の値を予測することはできません。

使用に関しては、定数は呼び出し元のコードに焼き付けられます。これは、ライブラリdll を再コンパイルしてパブリック定数を変更しても、コンシューマを変更しない場合、コンシューマは元の値を引き続き使用することを意味します。読み取り専用変数では、これは起こりません。これとは逆に、定数は (逆参照するのではなく) 値をロードするだけなので、(非常にわずかに) 高速です。

再インターン中。これは手動で行うこともできますが、最も一般的なのはリテラルのコンパイラ/ランタイム機能です。リテラルを介して読み取り専用フィールドを初期化する場合:

someField = "abc";

その後"abc"インターンとなります。構成から読み取ると、そうではありません。定数文字列はリテラルでなければならないため、これもインターンされますが、アクセス方法が異なります。ここでも、フィールドからの読み取りはldstr.

于 2009-01-04T09:37:56.920 に答える
13

実際、2 つのタイプは初期化後に変更することはできませんが、これらにはいくつかの違いがあります。

  • 「const」は、宣言されている場所 (コンパイル時) で初期化する必要がありますが、「readonly」は、宣言されている場所またはコンストラクター内 (ar ランタイム) で初期化できます。

たとえば、次のような状況で const を使用できます。

public class MathValues
{
  public const double PI = 3.14159;
}

そして、この場合には readonly の方が良いでしょう:

public class Person
{
    public readonly DateTime birthDate;

    public Person(DateTime birthDate)
    {
        this.birthDate = birthDate;
    }
}

また

public class Person
{
    public readonly DateTime birthDate = new DateTime(1986, 1, 24);
}
  • 「const」は静的であるため、そのクラスのすべてのインスタンス間で共有され、(MathValues.PI のように) 直接アクセスできますが、「readonly」は静的ではありません。結果として、const は static であるため、「static const」のような宣言は不正ですが、「static readonly」は有効です。

  • 'const' は、整数型 (sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool、または string)、列挙、または null への参照 (クラスではない) のみを保持できます。または構造は実行時に 'new' キーワードで初期化されるため)、'readonly' は複雑な型、構造体、またはクラスを (初期化で new キーワードを使用して) 保持できますが、列挙型を保持することはできません。

于 2009-01-04T10:09:31.007 に答える
5

定数について注意すべき点は、実際には実行可能ファイルに格納されるため、多くの定数を宣言すると実行可能ファイルのサイズが大きくなります。

通常、これは大きな問題ではありませんが、私の友人は、「すべてが const でなければならない」という規則を強制する会社で働いていて、コンパイルされた実行可能ファイルのサイズを大幅に増やすことに成功しました。

于 2009-01-04T09:31:27.807 に答える
5

C# .NET constreadonlystatic readonlyフィールドの違いを次に示します (この記事から)。

定数:

  • デフォルトで静的
  • コンパイル時の値が必要です (つまり、"A"+"B" は使用できますが、メソッド呼び出しは使用できません)。
  • 属性で使用可能
  • それらを使用するすべてのアセンブリにコピーされます (すべてのアセンブリは値のローカル コピーを取得します)
  • 関数内で宣言できます

読み取り専用インスタンス フィールド:

  • インスタンスの作成時に評価される
  • コンストラクターが終了するまでに値を設定する必要があります

静的読み取り専用フィールド:

  • コード実行がクラス参照にヒットしたときに評価されます (つまり、新しいインスタンスが作成されるか、静的メソッドが実行されます)。
  • 静的コンストラクターが完了するまでに値を評価する必要があります
  • これらに ThreadStaticAttribute を配置するのは本当に望ましくありません (静的コンストラクターは 1 つのスレッドでのみ実行され、そのスレッドの値が設定されるため、他のすべてのスレッドではこの値が初期化されていないため)。
于 2009-01-04T14:31:31.117 に答える
4

C#.Netのconstフィールドとreadonlyフィールドには顕著な違いがあります。

const はデフォルトで静的であり、後で変更できない定数値で初期化する必要があります。コンストラクターでも値の変更は許可されていません。すべてのデータ型で使用できるわけではありません。ex-DateTime の場合。DateTime データ型では使用できません。

public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public readonly string Name = string.Empty; //No error, legal

readonly は static として宣言できますが、必須ではありません。宣言時に初期化する必要はありません。その値は、コンストラクターを使用して割り当てまたは変更できます。そのため、インスタンス クラスのメンバーとして使用すると利点があります。2 つの異なるインスタンス化では、読み取り専用フィールドの値が異なる場合があります。例えば ​​-

class A
{
    public readonly int Id;

    public A(int i)
    {
        Id = i;
    }
}

次に、次のように、読み取り専用フィールドを特定の値で初期化できます。

A objOne = new A(5);
A objTwo = new A(10);

ここで、インスタンス objOne の readonly フィールドの値は 5 になり、objTwo の値は 10 になります。これは、const を使用して行うことはできません。

于 2014-12-15T12:54:48.587 に答える
2

もう一つ。見逃したかもしれませんが、上記のコメントにはこれがありませんでした。定数配列は作成できません。

private const int[] values = new int[] { 1, 2, 3 };

ただし、静的な読み取り専用フィールドを使用して作成できます。

private static readonly int[] values = new int[] { 1, 2, 3 };

したがって、許容値のリストなどの配列定数が必要で、列挙が適切でない場合は、静的読み取り専用が唯一の方法です。たとえば、配列が次のように null 許容整数の場合:

private static readonly int?[] values = new int?[] { null, 1, 2, 3 };

定数ではそれはできませんよね?

于 2009-04-16T12:45:03.167 に答える
2

使用中で?あまり。const はコンパイル時に評価されますが、readonly は実行時に評価されます。コンストラクターで読み取り専用変数に値を割り当てることもできます。

于 2009-01-04T09:28:46.783 に答える
1

違いは、静的読み取り専用フィールドの値は実行時に設定されるため、それを含むクラスによって変更できるのに対し、const フィールドの値はコンパイル時の定数に設定されることです。

静的な読み取り専用の場合、それを含むクラスはそれを変更することのみが許可されます

変数宣言内 (変数初期化子を介して) 静的コンストラクター内 (静的でない場合はインスタンス コンストラクター) static readonly は通常、フィールドの型が const 宣言で許可されていない場合、または値が不明な場合に使用されます。コンパイル時間。

インスタンスの読み取り専用フィールドも許可されます。

参照型の場合、どちらの場合も (静的とインスタンス)、readonly 修飾子は、フィールドへの新しい参照の割り当てを防止するだけであることに注意してください。特に、参照が指すオブジェクトを不変にするわけではありません。

class Program

{

  public static readonly Test test = new Test();

  static void Main(string[] args)

  {

     test.Name = "Program";

     test = new Test(); // Error: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

  }

}

class Test

{

   public string Name;

}

違いは、static read-only はそれを含むクラスによって変更できますが、const は決して変更できず、コンパイル時の定数に初期化する必要があることです。静的な読み取り専用のケースを少し拡張すると、それを含むクラスはそれを変更することしかできません。

-- 変数宣言内 (変数初期化子を介して)。

-- 静的コンストラクター (静的でない場合はインスタンス コンストラクター)。


C# .NET の Const キーワード

例:public const string abc = “xyz”; 宣言時のみ初期化。値はコンパイル時に評価され、実行時に変更することはできません。変更しようとすると、コンパイル エラーが発生します。Const はすでに一種の静的です。クラスと構造体は実行時に new キーワードで初期化されるため、定数をクラスまたは構造体に設定することはできません。ただし、整数型のいずれかである必要があります。C# .NET の読み取り専用キーワード

例:public readonly string abc; 宣言コードまたはコンストラクター コードで初期化できます。値は実行時に評価されます。静的またはインスタンス レベルの属性として宣言できます。読み取り専用フィールドは、実行時に new キーワードを使用して複雑なオブジェクトを保持できます。

于 2009-04-03T08:55:47.213 に答える
0

読み取り専用フィールドは、宣言時またはクラスのコンストラクターで初期化できます。したがって、読み取り専用フィールドは、使用するコンストラクターに応じて異なる値を持つことができます。

次の例のように、読み取り専用メンバーをランタイム定数に使用することもできます。

public static readonly uint currentTicks = (uint)DateTime.Now.Ticks;

読み取り専用フィールドは暗黙的に静的ではないため、必要に応じてstatic キーワードを読み取り専用フィールドに明示的に適用できます (必要です)。これは、暗黙的に静的である const フィールドでは許可されていません。

読み取り専用メンバーは、初期化時に new キーワードを使用して複雑なオブジェクトを保持できます。

于 2009-01-04T10:10:39.413 に答える