代码之家  ›  专栏  ›  技术社区  ›  Xaqron

C#相当于Visual Basic关键字:“With”…“End With”?

  •  8
  • Xaqron  · 技术社区  · 14 年前

    在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正在做什么一样)?

    7 回复  |  直到 12 年前
        1
  •  11
  •   Pieter van Ginkel    14 年前

    你不能用C#做这个。

    这个特性是VB特有的,在C中最接近的就是你描述的对象初始化器。

        2
  •  6
  •   ChaosPandion    14 年前

    这个怎么样?

    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;
            });
        }
    }
    
        3
  •  3
  •   Mark Byers    14 年前

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

    var x = myObject;
    x.property1 = something;
    x.property2 = something2;
    
        4
  •  3
  •   Community kfsone    7 年前

    为什么C没有VB.NET的“with”操作符?

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

    通过 @Jon Skeet

        5
  •  1
  •   Jon Hanna    14 年前

    为了向后兼容,VB.NET包含了VB6的一些设计缺陷。尽管Javascript也有同样的设计缺陷(事实上更糟的是 with 导致更多的模棱两可的构造),大多数其他C语法语言都没有,因此将其添加到C中没有向后兼容性好处。

        6
  •  1
  •   Community kfsone    7 年前

    @Mark Byers answer 很好,但是变量 x 将在设置属性后生效。你不能用名字 再次(在同一块)。

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

    void Main()
    {
        var myObject1 = new Foo();
        var myObject2 = new Hoo();
    
        //elided...
    
        {
            var _ = myObject1;
            _.MyPropertyA = 2;
            _.MyPropertyB = "3";
        }
    
        {
            var _ = myObject2;
            _.MyPropertyX = 5;
            _.MyPropertyY = "asd";
        }
    }
    
        7
  •  0
  •   supercat    13 年前

    如果“with”表达式是类类型,“with”语句相当于创建该类型的新临时变量,初始化为“with”表达式,并在每个前导“.”之前加上该变量。然而,如果它是一种结构类型,事情就更复杂了。考虑一下代码(显然不是人们通常写东西的方式,而是为了表明一点:

      With MyPoints(N) ' Array of Point
        N=SomeNewValue
        .X = MyPoints(N).X
        .Y = MyPoints(N).Y
      End With
    

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