9

在 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 正在做的那样),我该怎么做?

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再次使用名称(在同一块中)。

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

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”表达式,并在每个前导“.”之前。与那个变量。但是,如果它是结构类型,则事情会更加复杂。考虑一下代码(显然不是通常写东西的方式,而是按原样写来说明一点:

  With MyPoints(N) ' 点数组
    N=SomeNewValue
    .X = 我的积分(N).X
    .Y = 我的积分(N).Y
  结束于

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

于 2011-08-26T16:32:23.680 回答