GUIDはすべて0(ゼロ)ですか?


241

私は、Guidsでオブジェクトをやり取りするWCFサービスをいくつかテストしています。私のWebアプリのテストコードでは、次のようにしています。

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = new Guid()
});

何らかの理由で、new Guid()の呼び出しは、次のようにすべて0(ゼロ)のGuidを生成しています。

00000000-0000-0000-0000-000000000000

何が原因でしょうか?


9
編集後、これはまったく新しい質問です。そして、新しい答えを決定するには、さらに多くの情報が必要です。
Scott Rippey、

3
質問を変更した編集部分を削除しました。
Didaxis

115
+1この質問を使用して、空白のGUIDを数十回盗みました:)
jmosesman

5
@jmosesman、フォームを使用することをお勧めしますGuid.Empty
Jonathan Moosekian 2013

4
@JonathanM私は実際にSQLスクリプトで使用しています。この投稿は検索後に最初に表示されるだけです。
jmosesman 2013

回答:


428

Guid.NewGuid()デフォルトのコンストラクターを呼び出す代わりに、静的メソッドを使用します。

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = Guid.NewGuid()
});

18
正解の+1と適切なドキュメントへのリンク。
ObscureRobot 2011年

109

これから学ぶべき教訓:

1)GUIDは値型であり、参照型ではありません。

2)new S()任意の値型でデフォルトのコンストラクターを呼び出すと、それが何であれ、常にその値型のすべてゼロの形式が返されます。論理的にはと同じdefault(S)です。


3
それは同じILにコンパイルされますか、default(S)それとも欠けている微妙な点はありますか?
コンフィギュレー

8
@configurator:あります。実際、コンパイラの "default(S)"と "new S()"の内部表現は同じです。それらを内部で区別しないため、実際にはまったく同じではないため、長年にわたっていくつかの不幸なバグが発生しています。たとえばconst int x = new int();、仕様に従って合法であるとは考えられていませんが、そうconst int x = default(int);です。両方を許可します。
Eric Lippert、

1
@configurator-関連するコーナーケースに興味がある場合は、おそらくmsmvps.com/blogs/jon_skeet/archive/2008/12/10/…参考になります。
kvb

56

代わりにこれを試してください:

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = new Guid.NewGuid()
});

これにより、「実際の」Guid値が生成されます。参照タイプを新規作成すると、デフォルト値が与えられます(この場合、Guidの場合はすべてゼロです)。

新しいGuidを作成すると、Guidのデフォルト値であるすべてのゼロに初期化されます。これは基本的に「新しい」intを作成することと同じです(これは値の型ですが、とにかくこれを行うことができます)。

Guid g1;                    // g1 is 00000000-0000-0000-0000-000000000000
Guid g2 = new Guid();       // g2 is 00000000-0000-0000-0000-000000000000
Guid g3 = default(Guid);    // g3 is 00000000-0000-0000-0000-000000000000
Guid g4 = Guid.NewGuid();   // g4 is not all zeroes

これをintで同じことをするのと比較してください:

int i1;                     // i1 is 0
int i2 = new int();         // i2 is 0
int i3 = default(int);      // i3 is 0

1
g1ローカル変数としてではなく、フィールドとしてのみコンパイルされます。また、コメント列のインデックスがコードの同じ行と一致していません
CodesInChaos

1
@CodeInChaos:ありがとう、コメントを修正しました。参考までに、g1行は実際にコンパイルされます...
JohnD

3
そのままコンパイルされますが、定義された値はありません。(書き込む前に)それを読み取るコードを追加すると、コンパイルできなくなります。
CodesInChaos

1
正解ですが、初期化されていない変数を使用するとエラーが発生するため、値を使用できません。
JohnD

1
「Guid = Guid.NewGuid();」という行があるため、反対票が投じられました 新しい開発者を混乱させるかもしれません。「Guid someGuid = Guid.NewGuid();」のように編集することを検討してください。g2ラインのように;)
daviesdoesit



11

完全であることの精神において、あなたに使うように指示する答えGuid.NewGuid()は正しいです。

その後の編集に対処するには、RequestObjectクラスのコードを投稿する必要があります。あなたのguidプロパティがとしてマークされていないため、ネットワークDataMember上でシリアル化されていないと思われます。default(Guid)new Guid()(すべて0)と同じなので、これはあなたが見ている振る舞いを説明します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.