С# присваивать значения массива отдельным переменным в одной строке

Могу ли я назначить каждое значение в массиве для разделения переменных в одной строке на С#? Вот пример в коде Ruby того, что я хочу:

irb(main):001:0> str1, str2 = ["hey", "now"]
=> ["hey", "now"]
irb(main):002:0> str1
=> "hey"
irb(main):003:0> str2
=> "now"

Я не уверен, что то, что я хочу, возможно на С#.

Изменить: для тех, кто предлагает мне просто присваивать переменные переменные "эй" и "сейчас", это не то, что я хочу. Представьте себе следующее:

irb(main):004:0> val1, val2 = get_two_values()
=> ["hey", "now"]
irb(main):005:0> val1
=> "hey"
irb(main):006:0> val2
=> "now"

Теперь тот факт, что метод get_two_values возвращает строки "эй" и "сейчас", является произвольным. Фактически он может возвращать любые два значения, они даже не должны быть строками.

Ответы

Ответ 1

Это невозможно в С#.

Самое близкое, о чем я могу думать, это использовать инициализацию в той же строке с индексами

strArr = new string[]{"foo","bar"};
string str1 = strArr[0], str2 = strArr[1];

Ответ 2

Обновление: В С# 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 вне круглых скобок как аббревиатура:

var (first, middle, last) = LookupName(id1); // var outside

Вы также можете деконструировать существующие переменные с деконструированием Назначение:

(first, middle, last) = LookupName(id2); // deconstructing assignment

Деконструкция предназначена не только для кортежей. Любой тип может быть деконструирован, до тех пор, пока он имеет (декомпрессионный или расширительный) метод деконструктора форма:

public void Deconstruct(out T1 x1, ..., out Tn xn) { ... }

Параметры out представляют собой значения, которые деконструкция.

(Почему он использует параметры вместо возврата кортежа? так что вы можете иметь несколько перегрузок для разных номеров значения).

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/


Старый ответ:

Фактически, вы можете добиться аналогичной функциональности в С# с помощью таких методов расширения (обратите внимание: я не включаю проверку правильности аргументов):

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 и другими; список "переменных" легко читается.

  • Вы избегаете явно объявлять типы переменных, например, в решении Daniel Earwicker.

Недостатком является то, что вы получаете дополнительный блок кода, но я думаю, что это того стоит. Вы можете использовать фрагменты кода, чтобы избежать наложения фигурных скобок и т.д. Вручную.

Я знаю, что это вопрос сроком на 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 #, и я был вдохновлен этим ответом: fooobar.com/questions/96829/...

Ответ 3

Реальный реальный случай для этого - это удобный способ возврата нескольких значений из функции. Таким образом, это функция Ruby, которая возвращает фиксированное количество значений в массиве, а вызывающий объект хочет их в двух отдельных переменных. Именно здесь функция имеет наибольший смысл:

first_name, last_name = get_info() // always returns an array of length 2

Чтобы выразить это в С#, вы должны пометить два параметра с помощью out в определении метода и вернуть void:

public static void GetInfo(out string firstName, out string lastName)
{
    // assign to firstName and lastName, instead of trying to return them.
}

И так назовем это:

string firstName, lastName;
SomeClass.GetInfo(out firstName, out lastName);

Это не очень приятно. Надеюсь, какая-то будущая версия С# позволит:

var firstName, lastName = SomeClass.GetInfo();

Чтобы включить это, метод GetInfo вернет значение Tuple<string, string>. Это было бы непереломным изменением языка, поскольку текущие правовые применения var являются очень ограничительными, поэтому пока не существует допустимого использования синтаксиса "множественного объявления".

Ответ 4

Я не уверен, что то, что я хочу, возможно в С#.

Это не так.

Ответ 5

Вы можете сделать это в С#

string str1 = "hey", str2 = "now";

или вы можете быть похожим на это

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

Ответ 6

Вы можете сделать это в одной строке, но не как одно утверждение.

Например:

int str1 = "hey"; int str2 = "now";

Python и ruby ​​поддерживают задание, которое вы пытаетесь сделать; С# нет.

Ответ 7

Нет, но вы можете инициализировать массив строк:

string[] strings = new string[] {"hey", "now"};

Хотя это, вероятно, не слишком полезно для вас. Честно говоря, не сложно поставить их на две линии:

string str1 = "hey";
string str2 = "now";

Ответ 8

Теперь вы можете использовать именованные кортежи с С# 7.

{
  (string part1, string part2) = Deconstruct(new string[]{"hey","now"});
}

public (string, string) Deconstruct(string[] parts)
{
   return (parts[0], parts[1]);
}