简体   繁体   中英

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.

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.

不幸的是,这是不可能的。

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

没有与您的第一个示例等效的内容。

等价于您在第二个示例中编写的内容,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM