9

Visual Basic では、1 つのオブジェクトの複数のプロパティを変更する場合は、次のWith/End Withステートメントがあります。

Dim myObject as Object

// ' Rather than writing:
myObject.property1 = something
myObject.property2 = something2

// ' You can write:

with myObject
   .property1 = something
   .property2 = something2
   ...
End With

新しいオブジェクトを作成するときにC#ができることを私は知っています:

Object myObject = new Object { property1 = something, property2 = something2, ...};

myOjectしかし、 (Visual Basic が行っているように) が既に作成されている場合、どうすればよいでしょうか?

4

7 に答える 7

12

これは C# では実行できません。

この機能はVBに固有のものであり、C#で最も近いのは、説明したオブジェクト初期化子です。

于 2010-11-13T21:21:00.213 に答える
6

これはどう?

static class Extension
{
    public static void With<T>(this T obj, Action<T> a)
    {
        a(obj);
    }    
}

class Program
{
    class Obj
    {
        public int Prop1 { get; set; }
        public int Prop2 { get; set; }
        public int Prop3 { get; set; }
        public int Prop4 { get; set; }
    }

    static void Main(string[] args)
    {
        var detailedName = new Obj();
        detailedName.With(o => {
            o.Prop1 = 1;
            o.Prop2 = 2;
            o.Prop3 = 3;
            o.Prop4 = 4;
        });
    }
}
于 2010-11-13T21:25:45.427 に答える
3

大量の入力を避けたい場合は、オブジェクトに短い名前を付けることができます。

var x = myObject;
x.property1 = something;
x.property2 = something2;
于 2010-11-13T21:23:43.410 に答える
3

C# に VB.NET の「with」演算子がないのはなぜですか?

C# 言語の設計者を含む多くの人々は、'with' は読みやすさを損なうことが多く、祝福というよりもむしろ呪いと考えています。意味のある名前でローカル変数を宣言し、その変数を使用して単一のオブジェクトに対して複数の操作を実行する方が、一種の暗黙的なコンテキストを持つブロックを持つよりも明確です。

@ジョン・スキート

于 2010-11-13T21:30:27.827 に答える
1

VB.NETには、下位互換性のためにVB6の設計上の欠陥がいくつか含まれています。Javascriptには同じ設計上の欠陥がありますが(実際には、withよりあいまいな構造につながるため、さらに悪いものです)、他のほとんどのC構文言語にはないため、C#に追加しても下位互換性のメリットはありません。

于 2010-11-13T23:32:44.903 に答える
1

@Mark Byersの回答は良いですが、変数xはプロパティが設定された後に存続します。xまた、(同じブロック内で) name を再度使用することはできません。

これを試してください(そして、オブジェクトはこのサンプルでは参照型でなければなりません):

void Main()
{
    var myObject1 = new Foo();
    var myObject2 = new Hoo();

    //elided...

    {
        var _ = myObject1;
        _.MyPropertyA = 2;
        _.MyPropertyB = "3";
    }

    {
        var _ = myObject2;
        _.MyPropertyX = 5;
        _.MyPropertyY = "asd";
    }
}
于 2017-01-03T18:01:19.270 に答える
0

「with」式がクラス型の場合、「With」ステートメントは、その型の新しい一時変数を作成し、「With」式に初期化して、各先頭の「。」の前に置くことと同じです。その変数で。ただし、構造体タイプの場合は、さらに複雑になります。コードを考えてみてください(明らかに、通常の方法ではありませんが、要点を説明するためにそのまま記述されています。

  MyPoints(N)'ポイントの配列を使用
    N = SomeNewValue
    .X = MyPoints(N).X
    .Y = MyPoints(N).Y
  で終わる

「With」ステートメントは、MyPoints(N)への参照を効果的にラッチします。MyPointsが他の配列に変更された場合、またはNが変更された場合でも、ラッチされた参照は、Withステートメントが実行されたときと同じ配列の同じ要素を指します。ポイント型のローカル変数Pを宣言し、MyPoints(N)を取得してから、PXとPYに書き込む場合、書き込みは配列を更新するのではなく、ローカルコピーPにのみヒットします。C#で同様のセマンティクスを実現するには、ローカル変数を使用してMyPointsとNの両方を保持するか、Withステートメントの内容をPoint型のrefパラメーターを持つ無名関数内に配置する必要があります。実行時にクロージャを作成する必要をなくすために、無名関数は、おそらく参照によって、外部スコープから必要となるローカル変数も受け入れる必要があります。

于 2011-08-26T16:32:23.680 に答える