6

例 1

private const string _DefaultIconPath = _IconsPath + "default.ico";
private const string _IconsPath = "Icons/";

実行時のこれらの文字列の値:

  • _DefaultIconPath: "アイコン/default.ico"
  • _IconsPath: "アイコン/"

例 2

private readonly string _DefaultIconPath = _IconsPath + "default.ico";
private readonly string _IconsPath = "Icons/";

コンパイル時エラー:

A field initializer cannot reference the non-static field, method, or property '_IconsPath'

例 3

private static readonly string _DefaultIconPath = _IconsPath + "default.ico";
private static readonly string _IconsPath = "Icons/";

実行時のこれらの文字列の値:

  • _DefaultIconPath: "default.ico" (_IconsPath は に評価されnullます)
  • _IconsPath: "アイコン/"

質問

例 2 と同様に、例 3 でコンパイラがコンパイル エラーをスローしないのはなぜですか?

フィールド定義の場合は宣言の順序が重要ですが、static readonlyフィールド定義の場合は重要ではありませんconst

編集:

文字列がこれらの特定の値に初期化される理由を理解しています。私が理解していないのは、例 2 がコンパイル エラーをスローし、変数の宣言ではなくコンストラクターで初期化を強制する理由です (これは完全に理にかなっています) が、例 3 は同じように動作しません。静的コンストラクターで初期化を強制する同じコンパイル エラーをスローするのは理にかなっていませんか?


もう一つの例

private static string test = test2;
private static string test2 = test;

この例は、私が説明しようとしていることを示しています。コンパイラは、静的コンストラクターで静的状態の初期化を強制できます (インスタンス変数の場合と同様)。コンパイラがそれを許可するのはなぜですか (またはコンパイラがインスタンス変数に対してこれを許可しないのはなぜですか)?

4

3 に答える 3

0

2 つの無関係な問題があります。

1.コンパイルエラー

静的メンバーは、値を取得するためにクラスのインスタンスを必要としません。これが、静的メンバーから静的メンバーを参照しても問題が発生しない理由です。

インスタンス メンバーを初期化する場合this、コンストラクターから実行しない限り、メンバーを初期化しようとすると参照できません。

のフィールドをExample 2as としてマークしていないためstatic、それらのメンバーを参照する前に、それらを含むオブジェクトのインスタンスを最初にインスタンス化する必要があります。

であるからといって、そうであるとはreadonly限りませんstatic。読み取り専用フィールドは、宣言またはクラスのコンストラクターでインスタンス化できますが、クラスのすべてのインスタンスで共有されるわけではなく、適切なインスタンス化なしでアクセスすることもできません (明示的にstaticのように作成されていないと仮定しますExample 3)。

2.ヌル値

_IconsPathnullの理由はExample 3、フィールドが宣言され、順番にインスタンス化されるためです。順序を逆にすると、null ではないことがわかります。

于 2012-08-09T19:34:15.650 に答える
0

例 3 はstatic変数を使用しているため、許可されています。

例 2 は失敗します。これは、C# では変数初期化子が作成中のインスタンスを参照できないためです。Jon Skeet の説明はこちらを参照してください。

代わりにこれを行うことができます:

public class YourClass {
  private readonly string _IconsPath;
  private readonly string _DefaultIconsPath;

  public YourClass() {
    _IconsPath = "Icons/";
    _DefaultIconPath = _IconsPath + "default.ico";
  }
}
于 2012-08-09T19:38:28.320 に答える
0

例 2 の '_IconsPath' は初期化されていないため、使用できません。

例 3 では、静的フィールドにアクセスしています (ご存じのとおり)。MSDNによると完全に問題ありませんA static method, field, property, or event is callable on a class even when no instance of the class has been created.

ここで見る

更新: 例 3: 次と同じです:

private static readonly string _DefaultIconPath = MyStaticClass._IconsPath + "default.ico";
private static readonly string _IconsPath = "Icons/";

ポイントは、フィールドを使用していないことです(初期化されていない最愛の人、(「その他」/「新しい」)静的クラスを使用しています(静的な方法で使用する前に作成する必要はありません) .

于 2012-08-09T20:01:00.090 に答える