Question

In Visual Basic, if you are going to change multiple properties of a single object, there's a With/End With statement:

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:

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)?

Was it helpful?

Solution

You cannot do this in C#.

This feature is specific to VB and the closest you can come in C# is the object initializer like you describe.

OTHER TIPS

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?

Many people, including the C# language designers, believe that 'with' often harms readability, and is more of a curse than a blessing. 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

VB.NET includes some of VB6's design flaws for the sake of backward compatibility. 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#.

@Mark Byers answer is good but the variable x will live after properties are set. And you can't use name x again (in same block).

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

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 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). 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. If one declared a local variable P of type Point and grabbed MyPoints(N), and then write to P.X and P.Y, the writes would only hit the local copy P, rather than updating the array. 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. 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top