繁体   English   中英

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

[英]C# equivalent for Visual Basic keyword: '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#中做到这一点。

此功能特定于VB,您可以使用C#最接近的是您描述的对象初始值设定项。

这个怎么样?

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

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

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

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

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

@Jon Skeet提供

@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";
    }
}

VB.NET包含一些VB6的设计缺陷,以便向后兼容。 虽然JavaScript有相同的设计缺陷(的确是一个更糟糕的一个,因为它with导致更加模糊结构),其他大部分C-语法语言不这样做,所以没有向后兼容性的益处将它添加到C#。

如果“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),然后写入PX和PY,那么写入只会到达本地副本P,而不是更新数组。 要在C#中实现类似的语义,必须使用局部变量来保存MyPoints和N,或者将With语句的内容放在具有Point类型的ref参数的匿名函数中。 为了避免在运行时创建闭包,匿名函数也应该接受(可能通过引用)从外部作用域需要的任何局部变量。

暂无
暂无

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

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