Visual Basic关键字的C#等价物:’With’…’End With’?

在Visual Basic中,如果要更改单个对象的多个属性,则有一个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正在做的那样)?

你不能在C#中做到这一点。

此function特定于VB,您可以在C#中最接近的是您描述的对象初始值设定项。

这个怎么样?

 static class Extension { public static void With(this T obj, Action 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; }); } } 

如果您试图避免大量输入,可以为对象指定一个较短的名称:

 var x = myObject; x.property1 = something; x.property2 = something2; 

为什么C#没有VB.NET的’with’运算符?

很多人,包括C#语言设计师,都认为’with’常常会损害可读性,而且更多的是诅咒而不是祝福。 声明具有有意义名称的局部变量更明确,并使用该变量对单个对象执行多个操作,而不是使用具有某种隐式上下文的块。

由@Jon Skeet提供

VB.NET包含一些VB6的设计缺陷,以便向后兼容。 虽然Javascript具有相同的设计缺陷(实际上是更糟糕的一个,因为它会导致更模糊的构造),但大多数其他C语法语言都没有,因此将它添加到C#没有向后兼容性的好处。

如果“with”表达式是类类型,则“With”语句等效于创建该类型的新临时变量,初始化为“With”表达式,并在每个前导“。”之前。 用那个变量。 但是,如果它是结构类型,则事情会更复杂。 考虑一下代码(显然不是人们通常会写一些东西的方式,而是按照它来说明一点:

  使用MyPoints(N)'数组点
     N = SomeNewValue
     .X = MyPoints(N).X
     .Y = MyPoints(N).Y
  结束

“With”语句有效地锁存对MyPoints(N)的引用。 即使将MyPoints更改为其他某个数组,或者更改了N,锁定的引用仍将指向与执行With语句时相同的数组。 如果一个人声明了Point类型的局部变量P并抓住MyPoints(N),然后写入PX和PY,那么写入只会到达本地副本P,而不是更新数组。 要在C#中实现类似的语义,必须使用局部变量来保存MyPoints和N,或者将With语句的内容放在具有Point类型的ref参数的匿名函数中。 为了避免在运行时创建闭包,匿名函数也应该接受(可能通过引用)从外部作用域需要的任何局部变量。

@Mark Byers答案很好,但变量x将在设置属性后生效 。 并且您不能再次使用名称x (在同一块中)。

试试这个( 对象必须是此示例中的引用类型 ):

 void Main() { var myObject1 = new Foo(); var myObject2 = new Hoo(); //elided... { var _ = myObject1; _.MyPropertyA = 2; _.MyPropertyB = "3"; } { var _ = myObject2; _.MyPropertyX = 5; _.MyPropertyY = "asd"; } }