Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual Basic关键字的C#等价物:';使用'';以';结尾;?_C#_Vb.net_Language Design_With Statement - Fatal编程技术网

Visual Basic关键字的C#等价物:';使用'';以';结尾;?

Visual Basic关键字的C#等价物:';使用'';以';结尾;?,c#,vb.net,language-design,with-statement,C#,Vb.net,Language Design,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 = somethin

在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, ...};

但是,如果已经创建了
myObject
(就像Visual Basic正在做的那样),我该怎么做呢?

在C#中不能这样做。


此功能是VB特有的,在C语言中最接近的是您所描述的对象初始值设定项。

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

var x = myObject;
x.property1 = something;
x.property2 = something2;
这个怎么样

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;
        });
    }
}
静态类扩展
{
公共静态无效(此T对象,动作a)
{
a(obj);
}    
}
班级计划
{
Obj类
{
公共int Prop1{get;set;}
公共int Prop2{get;set;}
公共int Prop3{get;set;}
公共int Prop4{get;set;}
}
静态void Main(字符串[]参数)
{
var detailedName=new Obj();
detailedName.With(o=>{
o、 Prop1=1;
o、 Prop2=2;
o、 Prop3=3;
o、 Prop4=4;
});
}
}
为什么C#没有VB.NET的“with”操作符?

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


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

很好,但是变量
x
在设置属性后仍然有效。并且不能再次使用name
x
(在同一块中)

尝试此操作(此示例中的对象必须是引用类型):


是的,为了更进一步,你甚至可以使用(var x=myObject){/*newline*/x.property1=something;}@Alxandr:这是一个非常糟糕的主意,它会在块的末尾调用
Dispose
(甚至不会编译没有实现
IDisposable
)的类型。Oo.好的观点。我的坏观点。我只是认为它已经处理了这个问题“x"变量,但引用可能是致命的:-如果您希望变量在完成后超出范围,您可以将代码用大括号括起来以创建一个新范围。避免大量键入,真的吗?使用我们拥有的一流intellisense?!在我看来,这都是关于可读性的。将其作为一个扩展方法!然后您可以像
detailedName.With(o=>{o.Prop1=4})
和btw.+1用于创造力:-)注意:如果您使用充满漂亮的.NET扩展的Cadenza,您会得到一个方法,该方法正好具有以下实现:实际上在JavaScript中使用
With
有一个明显的优势。它允许您为您的功能引入新的作用域!VB中的“With”语句在与结构一起使用时,提供了C语言中不方便使用的语义。鉴于VB的“With”使用前导句点来避免歧义,我不确定您为什么会将其视为设计缺陷?…其他人认为VB的“With”语句是一个有用的特性,它提供了一些语义,而这些语义不是通过其他方式方便地实现的。有趣的是,他们将语法称为诅咒,然后几乎在对象初始化语法中复制了它……有一些人说它不好,但我想指出的是,微软的VB.NET编码惯例规定,在对一个对象进行一系列调用时,应该使用
With
关键字,这可能是
void Main()
{
    var myObject1 = new Foo();
    var myObject2 = new Hoo();

    //elided...

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

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