简体   繁体   English

Visual Basic关键字的C#等价物:'With'...'End With'?

[英]C# equivalent for Visual Basic keyword: 'With' … 'End With'?

In Visual Basic, if you are going to change multiple properties of a single object, there's a With/End With statement: 在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

I know C# can do it when creating a new object: 我知道C#可以在创建新对象时执行此操作:

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

But how do I do that if myOject is already created (like what Visual Basic is doing)? 但是如果已经创建了myOject (如Visual Basic正在做的那样),我该怎么做呢?

You cannot do this in C#. 你不能在C#中做到这一点。

This feature is specific to VB and the closest you can come in C# is the object initializer like you describe. 此功能特定于VB,您可以使用C#最接近的是您描述的对象初始值设定项。

How about this? 这个怎么样?

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;
        });
    }
}

If you're trying to avoid lots of typing you can give your object a shorter name: 如果您试图避免大量输入,可以为对象指定一个较短的名称:

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

Why doesn't C# have VB.NET's 'with' operator? 为什么C#没有VB.NET的'with'运算符?

Many people, including the C# language designers, believe that 'with' often harms readability, and is more of a curse than a blessing. 很多人,包括C#语言设计师,都认为'with'常常会损害可读性,而且更多的是诅咒而不是祝福。 It is clearer to declare a local variable with a meaningful name, and use that variable to perform multiple operations on a single object, than it is to have a block with a sort of implicit context. 声明具有有意义名称的局部变量并使用该变量对单个对象执行多个操作比使用具有某种隐式上下文的块更清楚。

by @Jon Skeet @Jon Skeet提供

@Mark Byers answer is good but the variable x will live after properties are set. @Mark Byers答案很好,但变量x将在设置属性后生效 And you can't use name x again (in same block). 并且您不能再次使用名称x (在同一块中)。

Try this ( And object must be reference type in this sample ) : 试试这个( 对象必须是此示例中的引用类型 ):

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

    //elided...

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

    {
        var _ = myObject2;
        _.MyPropertyX = 5;
        _.MyPropertyY = "asd";
    }
}

VB.NET includes some of VB6's design flaws for the sake of backward compatibility. VB.NET包含一些VB6的设计缺陷,以便向后兼容。 While Javascript has the same design flaw (indeed an even worse one, as its with leads to more ambiguous constructs), most other C-syntax languages don't, so there's no backward-compatibility benefit in adding it to C#. 虽然JavaScript有相同的设计缺陷(的确是一个更糟糕的一个,因为它with导致更加模糊结构),其他大部分C-语法语言不这样做,所以没有向后兼容性的益处将它添加到C#。

If the "with" expression is a class type, the "With" statement is equivalent to creating a new temporary variable of that type, initialized to the "With" expression, and preceding each leading "." 如果“with”表达式是类类型,则“With”语句等效于创建该类型的新临时变量,初始化为“With”表达式,并在每个前导“。”之前。 with that variable. 用那个变量。 If it is a structure type, however, things are more complicated. 但是,如果它是结构类型,则事情会更复杂。 Consider the code (obviously not the way one would normally write something, but written as it is to make a point: 考虑一下代码(显然不是人们通常会写一些东西的方式,而是按照它来写一个要点:

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

The "With" statement effectively latches a reference to MyPoints(N). “With”语句有效地锁存对MyPoints(N)的引用。 Even if MyPoints is changed to some other array, or N is changed, the latched reference will still point to the same element of the same array as it did when the With statement was executed. 即使将MyPoints更改为其他某个数组,或者更改了N,锁定的引用仍将指向与执行With语句时相同的数组。 If one declared a local variable P of type Point and grabbed MyPoints(N), and then write to PX and PY, the writes would only hit the local copy P, rather than updating the array. 如果一个人声明了Point类型的局部变量P并抓住MyPoints(N),然后写入PX和PY,那么写入只会到达本地副本P,而不是更新数组。 To achieve similar semantics in C#, one would have to either use local variables to hold both MyPoints and N, or else place the contents of the With statement within an anonymous function which has a ref parameter of type Point. 要在C#中实现类似的语义,必须使用局部变量来保存MyPoints和N,或者将With语句的内容放在具有Point类型的ref参数的匿名函数中。 To avoid having to create a closure at run-time, the anonymous function should also accept, probably by reference, any local variables it will need from the outer scope. 为了避免在运行时创建闭包,匿名函数也应该接受(可能通过引用)从外部作用域需要的任何局部变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM