C # эквивалент для ключевого слова Visual Basic: 'With' ... 'End With'? - PullRequest
8 голосов
/ 14 ноября 2010

В 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 ]

11 голосов
/ 14 ноября 2010

Вы не можете сделать это в C #.

Эта функция специфична для VB, и ближайший к вам C # - инициализатор объекта, как вы описали.

6 голосов
/ 14 ноября 2010

Как насчет этого?

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 голосов
/ 14 ноября 2010

Почему в C # нет оператора «с» в VB.NET?

Многие люди, включая разработчиков языка C #, считают, что «с» часто вредит читабельности,и это скорее проклятие, чем благословение.Более понятно объявить локальную переменную со значимым именем и использовать эту переменную для выполнения нескольких операций над одним объектом, чем иметь блок с неявным контекстом.

@ Jon Skeet

3 голосов
/ 14 ноября 2010

Если вы пытаетесь избежать много печатания, вы можете дать вашему объекту более короткое имя:

var x = myObject;
x.property1 = something;
x.property2 = something2;
1 голос
/ 03 января 2017

@ Марк Байерс ответит хорошо, но переменная 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";
    }
}
1 голос
/ 14 ноября 2010

VB.NET включает некоторые недостатки дизайна VB6 для обратной совместимости.Хотя у Javascript есть тот же недостаток дизайна (действительно, еще более худший, поскольку его with приводит к более неоднозначным конструкциям), большинство других языков C-синтаксиса этого не делают, поэтому нет преимущества обратной совместимости при добавлении его в C #.

0 голосов
/ 26 августа 2011

Если выражение «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.Если объявлена ​​локальная переменная P типа Point и захвачены MyPoints(N), а затем записывать в PX и PY, записи будут попадать только в локальную копию P, а не обновлять массив. Чтобы достичь аналогичной семантики в C #, нужно будет либо использовать локальные переменные для хранения как MyPoints, так и N,или же поместите содержимое оператора With в анонимную функцию, которая имеет параметр ref типа Point. Чтобы избежать необходимости создавать замыкание во время выполнения, анонимная функция должна также принимать, вероятно, посредством ссылки, любые локальные переменные, которые она будетнужно из наружного объема.

...