55

JavaScript has a nifty feature where you can assign several variables from properties in an object using one concise line. It's called destructuring assignment syntax which was added in ES6.

// New object
var o = {p1:'foo', p2:'bar', p3: 'baz'};
// Destructure
var {p1, p2} = o;
// Use the variables...
console.log(p1.toUpperCase()); // FOO
console.log(p2.toUpperCase()); // BAR

I want to do something similar with C#.

// New anonymous object
var o = new {p1="foo", p2="bar", p3="baz"};
// Destructure (wrong syntax as of C#6)
var {p1, p2} = o;
// Use the variables...
Console.WriteLine(p1.ToUpper()); // FOO
Console.WriteLine(p2.ToUpper()); // BAR

Is there a syntax to do this in C#?

2
  • what scenario required this feature, just curious! Commented Jun 24, 2020 at 14:47
  • 1
    @TechnicalSmile There is no requirement for this language feature (or any language feature for that matter). It's all syntactic sugar on top of zeros and ones :) In this case, I want to write less code and this is a feature that enables it. Commented Apr 20, 2021 at 16:21

4 Answers 4

36

Closest thing which could help you are Tuples.

C#7 maybe will have something like this:

public (int sum, int count) Tally(IEnumerable<int> values) 
{
    var res = (sum: 0, count: 0); // infer tuple type from names and values
    foreach (var value in values) { res.sum += value; res.count++; }
    return res;
}


(var sum, var count) = Tally(myValues); // deconstruct result
Console.WriteLine($"Sum: {sum}, count: {count}"); 

Link to discussion

Right now it is not possible.

Sign up to request clarification or add additional context in comments.

4 Comments

See updated link to the proposed feature
Yup, C# 7.0 supports deconstruction: blogs.msdn.microsoft.com/dotnet/2016/08/24/…
Tuples are the correct way to do this now that C#7 is here. In fact, I would even say that going forward, you should completely replace anonymous types with tuples because of the more elegant syntax. If your type has more properties than tuples support, you should be making a quick little class anyway.
28

C# 7 Using Tuples. You can achieve something like this.

You can construct and destruct a Tuple. Snippet

var payLoad = (
    Username: "MHamzaRajput",
    Password: "password",
    Domain: "www.xyz.com",
    Age: "24" 
);

// Hint: You just need to follow the sequence. 

var (Username, Password, Domain, Age) = payLoad;
// or
var (username, password, _, _) = payLoad;

Console.WriteLine($"Username: {username} and Password: {password}"); 

Output

Username: MHamzaRajput and Password: password

2 Comments

I get error CS0128: A local variable named _ is already defined in this scope. Do you need two different names for the underscores?
I have uploaded a snippet link you can test there.
9

The positional syntax for records comes with deconstruction by default (dotnet fiddle):

public record Person(string firstName, string lastName) {}

var person = new Person("Kyle", "Mit");
var (firstName, lastName) = person;
Console.WriteLine(firstName); // "Kyle"

Looking at the generated code via SharpLab, it just implements a regular Deconstruct method that you could add to your own type if you weren't using records:

[CompilerGenerated]
public void Deconstruct(out string firstName, out string lastName)
{
    firstName = this.firstName;
    lastName = this.lastName;
}

According to the docs on Deconstruction

C# doesn't offer built-in support for deconstructing non-tuple types other than the record and DictionaryEntry types. However, as the author of a class, a struct, or an interface, you can allow instances of the type to be deconstructed by implementing one or more Deconstruct methods.

1 Comment

Thanks! I particularly like that you can add public void Deconstruct to any class so this best answers the question! (the dotnet fiddle was a nice too so I could confirm it works)
3

I've been looking for something like this for a while now and I came across Deconstructor with Classes. This isn't as elegant of a solution as Javascript gives us, but it can definitely simplify a lot of things if done well.

Below is a small example (I have not run this code). I hope this helps others:

class Animal
{
    public string name;
    public string type;

    public Animal(
            string name, 
            string type
        )
    {
        this.name = name;
        this.type = type;
    }

    // Use out params with a 
    // method called Deconstruct
    public void Deconstruct(
            out string name, 
            out string type
        )
    {
        name = this.name;
        type = this.type;
    }
}

class Shelter
{
    public Animal[] animals;
    public int animalCapacity;
    public int numberOfAnimalsInShelter = 0;

    public Shelter(
            int animalCapacity
        )
    {
        this.animalCapacity = animalCapacity;
        animals = new Animal[animalCapacity];
    }

    public void AddAnimalToShelter(
            Animal animal
        )
    {
        animals[numberOfAnimalsInShelter] = animal;
        numberOfAnimalsInShelter++;
    }

    public void AnimalsInShelter()
    {
        for (int i = 0; i < animals.Length; i++)
            {
            // Here is how to use the Deconstructor 
            // method from the Animal class
                var (name, type) = animals[i];
                Console.WriteLine(name);
                Console.WriteLine(type);
            }
    }
}

Output should be the name and type for every animal that gets added to the shelter.

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.