String.Empty が定数ではないのはなぜですか?
質問
.Net では、なぜ String.Empty が定数ではなく読み取り専用なのでしょうか?その決定の背後にある理由を誰かが知っているかどうか疑問に思っています。
解決
その理由は、 static readonly
の代わりに使用されます const
ここで Microsoft が示しているように、アンマネージ コードで使用する予定です。 共有ソース共通言語インフラストラクチャ 2.0 リリース. 。見るファイルは sscli20\clr\src\bcl\system\string.cs
.
空の定数は空の文字列値を保持します。コンパイラがこれを文字通りとしてマークしないように、文字列コンストラクターを呼び出す必要があります。
これを文字通りとしてマークすることは、ネイティブからアクセスできるフィールドとして表示されないことを意味します。
この情報を見つけたのは、 CodeProject のこの便利な記事.
他のヒント
私はここで混乱と悪い応答がたくさんあると思います。
すべてのまず、const
フィールドはstatic
メンバー(のないインスタンスメンバーが)です。
C#言語仕様のセクション10.4定数を確認します。
の定数が考慮されているにもかかわらず 静的メンバ、定数宣言 どちらも必要としないでも、静的することができます 修飾子ます。
public const
メンバーが静的である場合は、、1は定数が新しいオブジェクトを作成することを検討することができませんでした。
この考えると、次のコード行は、新しいオブジェクトを作成する点で、の正確の同じことを行う。
public static readonly string Empty = "";
public const string Empty = "";
ここ2との違いを説明し、マイクロソフトからのメモがあります:
読み取り専用キーワードが異なっています constキーワード。 constのフィールドことができます 唯一の宣言時に初期化されます フィールドの。読み取り専用フィールドには、することができ いずれかの宣言時に初期化 またはコンストラクタインチそのため、 読み取り専用のフィールドは異なることができます コンストラクタに応じた値 中古。また、constのフィールドがありながら、 コンパイル時の定数、読み取り専用の フィールドには、実行時に使用することができます 定数は、...
だから私は、唯一のもっともらしい答えがここにジェフ・イェーツのがあることがわかります。
String.Empty read only instead of a constant?
あなたはの任意の文字列を一定にした場合、コンパイラはどこでもあなたがそれを呼び出すと、あなたはすべての上に、いつ同じ文字列を使用してコードを埋めるの実際の文字列のと交換している。<強いです>コードが実行され、異なるメモリデータから何度も何度もその文字列を読み取るために必要されています。
それはString.Empty
あるとしてあなたは一つだけの場所で読むあなたの文字列のままにすると、プログラムは一つだけの場所で同じ文字列を保持し、それを読んで、またはそれを参照してください - メモリの最小値のデータを維持する。
。また、あなたは、constのようString.Emptyのを使用して、任意のDLLをコンパイルした場合、およびcost
は、内のコードを実際に保つために作るので、何らかの理由String.Emptyの変更のために、そしてコンパイルdllが、これ以上同じように動作しません。すべての呼び出しで文字列のコピーます。
たとえば、このコードを参照してください。
public class OneName
{
const string cConst = "constant string";
static string cStatic = "static string";
readonly string cReadOnly = "read only string";
protected void Fun()
{
string cAddThemAll ;
cAddThemAll = cConst;
cAddThemAll = cStatic ;
cAddThemAll = cReadOnly;
}
}
のように、コンパイラによって来るされます。
public class OneName
{
// note that the const exist also here !
private const string cConst = "constant string";
private readonly string cReadOnly;
private static string cStatic;
static OneName()
{
cStatic = "static string";
}
public OneName()
{
this.cReadOnly = "read only string";
}
protected void Fun()
{
string cAddThemAll ;
// look here, will replace the const string everywhere is finds it.
cAddThemAll = "constant string";
cAddThemAll = cStatic;
// but the read only will only get it from "one place".
cAddThemAll = this.cReadOnly;
}
}
とアセンブリの呼び出し
cAddThemAll = cConst;
0000003e mov eax,dword ptr ds:[09379C0Ch]
00000044 mov dword ptr [ebp-44h],eax
cAddThemAll = cStatic ;
00000047 mov eax,dword ptr ds:[094E8C44h]
0000004c mov dword ptr [ebp-44h],eax
cAddThemAll = cReadOnly;
0000004f mov eax,dword ptr [ebp-3Ch]
00000052 mov eax,dword ptr [eax+0000017Ch]
00000058 mov dword ptr [ebp-44h],eax
編集:修正さタイポ
この答えが存在するための歴史。
もともと:
ので String
クラスですが、そのためになることはできない定数です。
長討論:
多くの有用したダイアログに打ち出し、船体のこの回答ではなく削除すると、このコンテンツの再生に直接:
ます。益とは異なりJava)文字列、文字列は完全に同じなのです。りできるのは、文字列定数です。ネDrJokepu月3'09 16:57
言ってるのかわからねーとするクラスではないです定数?–StingyJack月3'09 16:58
はい、オブジェクトには使用読み取り専用になります。みが構造体でない定数.と思いき
string
の代わりにString
コンパイラの変化にconstへの読み取り専用になります。すべてのいをCプログラマー。–ゲリー Shutler月3'09 16:59tvanfossonだけでは説明ではエクスペディアのキャンセルにデフォルト値が設定され."Xできない一定では、Yを含むクラス"は、ほんの少しでも文脈自由;)–Leonidas月3'09:17:01
文字列になります。空の静的なプロパティを返すインスタンスの文字列クラス、すなわち、空の文字列は、文字列のクラスそのものです。–tvanfosson月3'09:17:01
空が読み取り専用インスタンスでない財)文字列のクラスです。–senfo月3'09:17:02
ヘッドを傷つけ.たなければならないと思い私は、今は未確定できます。研究に必要な!–ゲリー Shutler月3'09:17:07
空の文字列がインスタンスの文字列のクラスです。空はstaticフィールドではない物件からの修正の文字列クラスです。基本的に差ポインタのことでポイントです。ればな読み取り専用になりますが変化するインスタンスの空分野をさします。–tvanfosson月3'09:17:07
ゲリーではなく、必要な研究です。しかしよく考えてください。文字列は、クラスです。空のインスタンスの文字列になります。–senfo月3'09:17:12
何かありませんか取得す:どのように地球上に静的コンストラクタは、文字列のクラスのインスタンスを生成し文字列です。ことはできないので何らかの"鶏と卵の"シナリオ?–DrJokepu月3'09:17:12 5
この答えが正しい近くのその他のクラスです。文字列になります。.当期純な多くの性能特殊なケーシングのための文字列、およびそのひとつは、たとえできる文字列定数は、アクセスすることとする。この場合、ジェフ-イェーツの正しい答えです。–ジョエル-ミューラー月3'09 19:25
に記載のとおり§7.18、常に表現で表現できる十分に評価でコンパイルします。以来を作成する唯一の方法は非null値の参照型以外の文字列は、新しいオペレーターからの新しいオペレーターが許可されない一定表現の値の定数参照-種類以外の文字列はnullに設定されます。以前のコメントしたから直接C#言語仕様、努ジョエル-ミュラー。–senfo月4'09 15:05 5