3

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.
    }
}
Arseni Mourzenko
  • 50,338
  • 35
  • 112
  • 199

4 Answers4

5

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,
    // ...
};
mqp
  • 70,359
  • 14
  • 95
  • 123
  • 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 Aug 30 '10 at 18:28
  • 2
    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. – mqp Aug 30 '10 at 18:36
  • 1
    @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 Aug 30 '10 at 18:43
  • @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 Sep 02 '10 at 19:23
  • @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 Sep 02 '10 at 19:39
2

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;}
}
Kris van der Mast
  • 16,343
  • 8
  • 39
  • 61
  • Here's the C# Programming Guide link: http://msdn.microsoft.com/en-us/library/bb384062.aspx – Trevor Robinson Aug 30 '10 at 18:29
  • 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. – Arseni Mourzenko Aug 30 '10 at 18:39
1

"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
  • 101,701
  • 37
  • 181
  • 258
0

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
  • 344
  • 4
  • 9