views:

107

answers:

4

Hi,

PHP has a language construct list() which provides multiple variables assignment in one statement.

$a = 0;
$b = 0;
list($a, $b) = array(2, 3);
// Now $a is equal to 2 and $b is equal to 3.

Is there a similar thing in C#?

If not, is there any workaround which may help to avoid code like the following, without having to deal with reflection?

public class Vehicle
{
    private string modelName;
    private int maximumSpeed;
    private int weight;
    private bool isDiesel;
    // ... Dozens of other fields.

    public Vehicle()
    {
    }

    public Vehicle(
        string modelName,
        int maximumSpeed,
        int weight,
        bool isDiesel
        // ... Dozens of other arguments, one argument per field.
        )
    {
        // Follows the part of the code I want to make shorter.
        this.modelName = modelName;
        this.maximumSpeed = maximumSpeed;
        this.weight= weight;
        this.isDiesel= isDiesel;
        /// etc.
    }
}
+5  A: 

No, I'm afraid there isn't any good way to do that, and code like your example gets written often. It sucks. My condolences.

If you're willing to sacrifice encapsulation for concision, you can use object initializer syntax instead of a constructor for this case:

public class Vehicle
{
    public string modelName;
    public int maximumSpeed;
    public int weight;
    public bool isDiesel;
    // ... Dozens of other fields.
}

var v = new Vehicle {
    modelName = "foo",
    maximumSpeed = 5,
    // ...
};
mquander
Beat me to it. +1
Ryan Bennett
There's no need to sacrifice encapsulation if you use automatic properties (C# 3.0 and later, as are object initializers): http://msdn.microsoft.com/en-us/library/bb384054.aspx
Trevor Robinson
There is still a sacrifice; the `set` accessor on the property needs to be public (or accessible to wherever you're initializing it) in order to use object initialization syntax. If you wanted the property to be read-only after construction, you're out of luck.
mquander
@Trevor public (dumb) setters break encapsulation. There's no more encapsulation in public string Foo{get;set;} than in public string Foo; (and properties including a bunch of those in the framework only makes it too easy to violate Demeter's law)
Rune FS
@Rune: It depends what you mean by encapsulation. If you mean you didn't want a publicly settable property in the first place, then yes. High-level objects with lots of settable properties are symptomatic of poor OO design. (Low-level data objects, e.g. for serialization, might be another matter.) However, I was referring to the fact that automatic properties are not as bad as public variables, since the fact that the setter is trivial is hidden from clients, and its implementation is free to change later.
Trevor Robinson
@trevor http://en.m.wikipedia.org/wiki/Law_of_Demeter?wasRedirected=true. Any property returning a field (including autoproperties) is a violation of the law of demeter. Since using the returned value is trusting a friend of a friend and not only trusting your nearest friend
Rune FS
+2  A: 

I think you're looking for object and collection initializers.

var person = new Person()
{
    Firstname = "Kris",
    Lastname = "van der Mast"
}

for example where Firstname and Lastname are both properties of the class Person.

public class Person
{
    public string Firstname {get;set;}
    public string Lastname {get;set;}
}
XIII
Here's the C# Programming Guide link: http://msdn.microsoft.com/en-us/library/bb384062.aspx
Trevor Robinson
@XIII: no, I can't use this in my case, since there are already properties, containing setters which perform some validity checks and operations. But this could be used in the `Vehicle` code sample.
MainMa
+1  A: 

"Multiple variable initialization" or "Multiple variable assignment" ?

For initialization

$a = 0; 
$b = 0; 
list($a, $b) = array(2, 3); 

would be:

 int a=2, b=3;

For assignment, there's no shortcut. It has to be two statement, but if you like, you can put the two statements on one line:

 a=2; b=3;
James Curran
@James Curran: there was an error in my question. I was talking about multiple variable *assignment*. Thanks to note it.
MainMa
A: 

Yes - you can eliminate all the code in the constructor with object initializers (new for C# 3.0). Here is a pretty good explanation:

http://weblogs.asp.net/dwahlin/archive/2007/09/09/c-3-0-features-object-initializers.aspx

Inverseofverse