Variable to list assignment in C#?

In PHP you can write

$arr = array(1,2);
list($a, $b) = $arr;

Which is basically the equivalent of

$a = $arr[0];
$b = $arr[1];

Is there an equivalent in C#?


Just bugs me because so often I write things like

var split = action.Split('.');
string controllerName = split[0];
string actionName = split[1];

And split is just a throw-away variable that I can never think of a decent name for. "chunks", "bits", "pieces", "parts",... all meaningless jibberish.

Answers


You could write your own method, like:

int[] arr = new[] { 1, 2 };

int a, b;
Populate(arr, out a, out b);

static void Populate<T>(T[] arr, out T t1, out T t2)
{
    t1 = arr[0];
    t2 = arr[1];
}

I wouldn't recommend it, though...You'd have to be careful about having the right number of parameters, and I don't think there's a way to do an arbitrary size - C# has the concept of "params array" in the signature, but I don't think you can do it with "out" parameters.


Other than this?

a = arr[0];
b = arr[1];

No.


Unfortunately, this is not possible.


To expand on Joe's solution, the input doesn't have to be an array. It can be an IEnumerable<T>, allowing you to pass any source of data. And once you do that, it starts looking like it should be an extension method. Furthermore, rather than always assuming that there will be as many items in the collection as there are input parameters, sometimes it's convenient to allow mismatches in numbers.

public static void AssignTo<T>(this IEnumerable<T> source, out T dest1, out T dest2)
{
    using (var e = source.GetEnumerator())
    {
        dest1 = e.MoveNext() ? e.Current : default(T);
        dest2 = e.MoveNext() ? e.Current : default(T);
    }
}

Then this code:

string x, y;
"x".Split(',').AssignTo(out x, out y);
Console.WriteLine(x + ", " + y);
"x,y".Split(',').AssignTo(out x, out y);
Console.WriteLine(x + ", " + y);
"x,y,z".Split(',').AssignTo(out x, out y);
Console.WriteLine(x + ", " + y);

will output:

x,
x, y
x, y

Why would you ever want to allow the wrong size list passed in? Let's say you're parsing query strings. In Python you would want to say key, value = query.split('=') but that won't work because key is a valid query and you could get key=value=value too, both of which would cause an exception. Ordinarily you'd have to write

string[] kv = query.Split('=');
string key = kv[0];
string value = kv.Length > 1 ? kv[1] : null;

but instead you can just write

string key, value;
query.Split('=').AssignTo(out key, out value);

If you require the exact number of arguments though, just throw an exception instead of assigning null:

public static void AssignToExact<T>(this IEnumerable<T> source, out T dest1, out T dest2)
{
    using (var e = source.GetEnumerator())
    {
        if (e.MoveNext()) dest1 = e.Current;
        else throw new ArgumentException("Only 0 of 2 arguments given", "source");
        if (e.MoveNext()) dest2 = e.Current;
        else throw new ArgumentException("Only 1 of 2 arguments given", "source");
        if (e.MoveNext()) throw new ArgumentException("More than 2 arguments given", "source");
    }
}

There's no equivalent to your first example.


The equivalent would be what you have written in your second example,


Need Your Help

Why am I getting a FileNotFound exception when referencing another project from the same solution?

c# .net nunit

I am learning how to use NUnit. I have my main project in it's solution, and created a separate project in that same solution which will hold my unit tests, with it's own namespace. From that pro...

WCF - Service Contract from another assembly

c# wcf assemblies

I have tried googling for an answer since last week and haven't found anything. Maybe I'm just searching with incorrect key words...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.