web-dev-qa-db-ja.com

C#でクラスインスタンスを定数として宣言するにはどうすればよいですか?

これを実装する必要があります:

static class MyStaticClass
{
    public const TimeSpan theTime = new TimeSpan(13, 0, 0);
    public static bool IsTooLate(DateTime dt)
    {
        return dt.TimeOfDay >= theTime;
    }
}

theTimeπと同じように定数(真剣に:-)です。私の場合、たとえば設定から読み取ることは無意味です。そして、一度初期化され、変更されないようにしたいと思います。

しかし、C#では、関数(コンストラクター)による定数の初期化は許可されていないようです。これを克服する方法は?

36
Ivan

readonlyの代わりにconstを使用すると、初期化でき、その後は変更できません。それはあなたが探しているものですか?

コード例:

static class MyStaticClass
{
    public static readonly TimeSpan theTime;
    static MyStaticClass
    {
        theTime = new TimeSpan(13, 0, 0)
    }
}
60
ashelvey

定数はコンパイル時定数である必要があり、コンパイラはコンパイル時にコンストラクタを評価できません。 readonly および staticコンストラクター を使用します。

static class MyStaticClass
{
  static MyStaticClass()
  {
     theTime = new TimeSpan(13, 0, 0);
  }

  public static readonly TimeSpan theTime;
  public static bool IsTooLate(DateTime dt)
  {
    return dt.TimeOfDay >= theTime;
  }
}

一般に、初期化の順序を制御できるので、直接割り当てではなくコンストラクタで初期化することを好みます。

37
James Gaunt

C#のconstは、C++のconstと同じ意味を持ちません。 C#では、constを使用して本質的にリテラルのエイリアスを定義します(したがって、リテラルでのみ初期化できます)。 readonlyはあなたが望むものに近くなりますが、代入演算子にのみ影響することに注意してください(クラスは不変のセマンティクスを持たない限り、オブジェクトは実際には一定ではありません)。

10

このリンク から:

定数は、値型(sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、またはbool)、列挙、文字列リテラル、またはnullへの参照でなければなりません。

オブジェクトを作成する場合は、static readonly

static class MyStaticClass
{
  public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);
  public static bool IsTooLate(DateTime dt)
  {
    return dt.TimeOfDay >= theTime;
  }
}
7
John Leehey
public static readonly TimeSpan theTime = new TimeSpan(13, 0, 0);
4
lance

定数は、値が決して変更できない静的メンバーを表します。つまり、コンパイル時に定数値が定義されます。
声明で:

    public const TimeSpan theTime = new TimeSpan(13, 0, 0);

定数フィールドの2つの公理に違反しています:

  • C#組み込み型(System.Objectを除く)のみがconstとして宣言できます
  • 初期化値はコンパイル時に評価する必要があります

質問では、TimeSpanタイプが使用されていますが、これはbuilt-in(predefined) Typeではありません。これは、csc.exeコンパイラがそれを認識できないことを意味します。
組み込みのC#型(たとえば、String)を使用し、コンパイル時の値で定数メンバーを初期化する場合、引き続きエラーが発生します。

 public const string MyNumber = SetMyString();
 private string SetMyString()
 {
  return "test";
 }

問題を解決するには、次の方法でメンバーを宣言できます。

static readonly

実行時にフィールドを1回だけ宣言する場合の修飾子:

public static readonly string MyNumber = SetMyString();
private static string SetMyString()
{
 return "test";
}
1
George Kargakis

Readonlyキーワードを使用できます。

フィールド宣言に読み取り専用修飾子が含まれる場合、宣言によって導入されたフィールドへの割り当ては、宣言の一部として、または同じクラスのコンストラクターでのみ発生します。

例(リンクされたMSDNページからコピー):

class Age
{
    readonly int _year;
    Age(int year)
    {
        _year = year;
    }
    void ChangeYear()
    {
        //_year = 1967; // Compile error if uncommented.
    }
}
0
Rudresh Bhatt