web-dev-qa-db-ja.com

C#newステートメントの後の中括弧は何をしますか?

以下のコードを考えると、方法position0が初期化され、方法position1は初期化されていますか?それらは同等ですか?そうでない場合、違いは何ですか?

class Program
{
    static void Main(string[] args)
    {
        Position position0 = new Position() { x=3, y=4 };

        Position position1 = new Position();
        position1.x = 3;
        position1.y = 4;
    }
}

struct Position
{
    public int x, y;
}
59

オブジェクトおよびコレクションの初期化子。オブジェクトのフィールドを初期化するために使用されます。

http://msdn.Microsoft.com/en-us/library/bb384062.aspx

それらは、ほぼ同等の同等のILを生成します。ジョン・スキートは、実際に何が起こっているのかについての答えを持っています。

46
Joshua Rodgers

それらはquite同等ではありません-少なくとも一般的な場合はそうではありません。オブジェクト初期化子を使用するコードはこれに近いです:

Position tmp = new Position();
tmp.x = 3;
tmp.y = 4;
Position position1 = tmp;

言い換えると、変数への割り当ては、プロパティが設定された場合にのみ発生します。これで、新しいローカル変数を宣言する場合、それは実際には重要ではなく、コンパイラーは最初の形式に最適化する可能性があります。しかし、論理的には重要です。考慮してください:

Position p1 = new Position { x = 10, y = 20 };

p1 = new Position { x = p1.y, y = p1.x };

それがp1firstに割り当てた場合、p1.xp1.yの両方が0になります。これは実際には次と同等です:

Position tmp = new Position();
tmp.x = 10;
tmp.y = 20;
Position p1 = tmp;

tmp = new Position();
tmp.x = p1.y; // 20
tmp.y = p1.x; // 10
p1 = tmp;

編集:クラスではなく構造体を使用していることに気付きました。それはいくつかの微妙な違いをもたらすかもしれません...しかし、あなたはほとんど確実に:)から始めるために可変構造を使用するべきではありません

58
Jon Skeet

これはオブジェクトの初期化子であり、単一の式で値を割り当てることができます。最も重要なことは、これはLINQ内でも匿名型(それ以外では不変)でも機能することです。 addiアイテムを新しいコレクションに追加する同様のコレクション初期化構文もあります。

役に立つ微妙なタイミングの問題があることに注意してください。初期化子では、すべての割り当て/追加が発生しますbefore変数が割り当てられます。これにより、他のスレッドが不完全なオブジェクトを見ることを防ぐことができます。そうしないと、同じ結果を得るために追加の変数が必要になります。

7
Marc Gravell

ILのすべてを忘れて、それは単なる略記法です。あなたがしていることはこれです:

a。 1つのケースでは、デフォルトのコンストラクタを明示的に使用してから、2つのプロパティを設定しています。

b。もう1つは、ケースaで行ったことを暗黙的にコンパイラーに実行させる新しい初期化構文を使用していることです。

ILのサブテルスにもかかわらず、彼らはあなたのために同じことを達成します。

2
awrigley

2つのコードサンプルは同じILを生成します。 (少なくともリリースビルドでは)

2
SLaks

これらは完全に同等です。コンパイラは実際には、最初のバージョンを2番目のバージョンに変換するだけです。

2つの唯一の違いは、最初のメソッドでは、初期化されたバージョンをメソッドに渡すなど、Nice Thinsを実行できることです。

DoSomethingWithPoint(new Position() { x=3, y=4 });

これは、2番目の初期化例よりもはるかに多くのコード行です。

1

読みやすいという点を除いて、これらは同等です。

また、新しいオブジェクトを別の場所に渡す場合も考慮してください。

var aList = new List<Position>();
aList.Add( new Position() { x=3, y=4 } );
1
Dan Byström