Обновление: В C # 7 вы можете легко назначать несколько переменных одновременно, используя кортежи. Чтобы назначить элементы массива переменным, вам нужно написать соответствующие методы расширения Deconstruct()
:
Еще один способ использования кортежей - деконструировать их. Деконструкция
Объявление - это синтаксис для разделения кортежа (или другого значения) на
его части и присвоение этих частей по отдельности новым переменным:
(string first, string middle, string last) = LookupName(id1); // deconstructing declaration
WriteLine($"found {first} {last}.");
В декларации деконструкции вы можете использовать var для индивидуального
объявленные переменные:
(var first, var middle, var last) = LookupName(id1); // var inside
Или даже поставить одну переменную за скобками как
аббревиатура:
var (first, middle, last) = LookupName(id1); // var outside
Вы также можете деконструировать в существующие переменные с деконструкцией
Назначение:
(first, middle, last) = LookupName(id2); // deconstructing assignment
Деконструкция не только для кортежей. Любой тип может быть деконструирован,
до тех пор, пока он имеет (экземпляр или расширение) метод деконструктора
форма:
public void Deconstruct(out T1 x1, ..., out Tn xn) { ... }
Выходные параметры представляют собой значения, которые являются результатом
деконструкция.
(Почему он использует параметры вместо возврата кортежа?
так что вы можете иметь несколько перегрузок для разных номеров
значения).
class Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) { X = x; Y = y; }
public void Deconstruct(out int x, out int y) { x = X; y = Y; }
}
(var myX, var myY) = GetPoint(); // calls Deconstruct(out myX, out myY);
Будет обычным делом иметь конструкторов и деконструкторов
«Симметричный» таким образом.
https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/
Старый ответ:
Фактически, вы можете достичь аналогичной функциональности в C #, используя такие методы расширения (примечание: я не включил проверку правильности аргументов):
public static void Match<T>(this IList<T> collection, Action<T,T> block)
{
block(collection[0], collection[1]);
}
public static void Match<T>(this IList<T> collection, Action<T,T,T> block)
{
block(collection[0], collection[1], collection[2]);
}
//...
И вы можете использовать их так:
new[] { "hey", "now" }.Match((str1, str2) =>
{
Console.WriteLine(str1);
Console.WriteLine(str2);
});
В случае, если требуется возвращаемое значение из функции, будет работать следующая перегрузка:
public static R Match<T,R>(this IList<T> collection, Func<T, T, R> block)
{
return block(collection[0], collection[1]);
}
private string NewMethod1()
{
return new[] { "hey", "now" }.Match((str1, str2) =>
{
return str1 + str2;
});
}
Таким образом:
Вам не нужно повторять имя массива, как в решении, предложенном JaredPar и другими; список «переменных» легко читается.
Вам не нужно явно объявлять типы переменных, как в решении Даниэля Эрвикера.
Недостаток в том, что вы получаете дополнительный блок кода, но я думаю, что оно того стоит. Вы можете использовать фрагменты кода, чтобы не вводить фигурные скобки и т.д. вручную.
Я знаю, что это вопрос 7 лет, но не так давно мне нужно было такое решение - легко давать имена элементам массива, передаваемым в метод (нет, использование классов / структур вместо массивов нецелесообразно, поскольку для одних и тех же массивов мне могут понадобиться разные имена элементов в разных методах) и, к сожалению, я получил такой код:
var A = points[0];
var A2 = points[1];
var B = points[2];
var C2 = points[3];
var C = points[4];
Теперь я мог бы написать (на самом деле, я сейчас реорганизовал один из этих методов!):
points.Match((A, A2, B, C2, C) => {...});
Мое решение похоже на сопоставление с образцом в F #, и я был вдохновлен этим ответом: https://stackoverflow.com/a/2321922/6659843