Переменная для назначения списка в C #? - PullRequest
1 голос
/ 30 декабря 2010

В PHP вы можете написать

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

Что в основном эквивалентно

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

Есть ли эквивалент в C #?


Просто ошибкименя, потому что так часто я пишу такие вещи, как

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

и split - это просто одноразовая переменная, для которой я никогда не могу придумать подходящего имени.«куски», «кусочки», «кусочки», «кусочки», ... все бессмысленное чепуха.

Ответы [ 6 ]

5 голосов
/ 30 декабря 2010

Вы можете написать свой собственный метод, например:

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];
}

Я бы не рекомендовал его, хотя ... Вы должны быть осторожны с правильным количеством параметров, и я не будуНе думаю, что есть способ сделать произвольный размер - в C # есть понятие «массив params» в сигнатуре, но я не думаю, что вы можете сделать это с параметрами «out».

2 голосов
/ 30 декабря 2010

Чтобы расширить на решение Джо , входные данные не должны быть массивом. Это может быть IEnumerable<T>, что позволяет передавать любой источник данных. И как только вы это сделаете, он начинает выглядеть так, как будто это должен быть метод расширения. Кроме того, вместо того, чтобы всегда предполагать, что в коллекции будет столько элементов, сколько и входных параметров, иногда удобно допускать несовпадения чисел.

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

Тогда этот код:

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

выведет:

x,
x, y
x, y

Почему вы хотите разрешить передачу неверного списка размеров? Допустим, вы анализируете строки запроса. В Python вы хотели бы сказать key, value = query.split('='), но это не сработает, потому что key является допустимым запросом, и вы также можете получить key=value=value, оба из которых могут вызвать исключение. Обычно вам нужно написать

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

но вместо этого вы можете просто написать

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

Если вам требуется точное количество аргументов, просто бросьте исключение вместо присвоения нуля:

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");
    }
}
2 голосов
/ 30 декабря 2010

К сожалению, это невозможно.

2 голосов
/ 30 декабря 2010

Кроме этого?

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

номер

1 голос
/ 30 декабря 2010

Эквивалентом будет то, что вы написали во втором примере,

1 голос
/ 30 декабря 2010

Нет эквивалента вашему первому примеру.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...