C# 将数组的值分配给一行中的分隔变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1422155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 16:22:07  来源:igfitidea点击:

Assign values of array to separate variables in one line

c#arraysstringinitializationdeclaration

提问by Sarah Vessels

Can I assign each value in an array to separate variables in one line in C#? Here's an example in Ruby code of what I want:

我可以将数组中的每个值分配给 C# 中一行中的单独变量吗?这是我想要的 Ruby 代码示例:

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

I'm not sure if what I'm wanting is possible in C#.

我不确定我想要的东西在 C# 中是否可行。

Edit:for those suggesting I just assign the strings "hey" and "now" to variables, that's not what I want. Imagine the following:

编辑:对于那些建议我只将字符串“hey”和“now”分配给变量的人,这不是我想要的。想象一下:

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

Now the fact that the method get_two_valuesreturned strings "hey" and "now" is arbitrary. In fact it could return any two values, they don't even have to be strings.

现在,该方法get_two_values返回字符串“hey”和“now”的事实是任意的。事实上,它可以返回任意两个值,它们甚至不必是字符串。

采纳答案by JaredPar

This is not possible in C#.

这在 C# 中是不可能的。

The closest thing I can think of is to use initialization in the same line with indexs

我能想到的最接近的事情是在索引的同一行中使用初始化

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

回答by Randolpho

You can do it in one line, but not as one statement.

您可以在一行中完成,但不能作为一个语句完成。

For example:

例如:

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

Python and ruby support the assignment you're trying to do; C# does not.

Python 和 ruby​​ 支持您尝试执行的任务;C# 没有。

回答by sepp2k

I'm not sure if what I'm wanting is possible in C#.

我不确定我想要的东西在 C# 中是否可行。

It's not.

它不是。

回答by Ron Warholic

No, but you can initialize an array of strings:

不,但您可以初始化一个字符串数组:

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

Although that's probably not too useful for you. Frankly its not hard to put them on two lines:

虽然这对你来说可能不太有用。坦率地说,将它们放在两行并不难:

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

回答by Daniel Earwicker

The real-world use case for this is providing a convenient way to return multiple values from a function. So it is a Ruby function that returns a fixed number of values in the array, and the caller wants them in two separate variables. This is where the feature makes most sense:

实际用例是提供一种从函数返回多个值的便捷方法。所以它是一个 Ruby 函数,它返回数组中固定数量的值,调用者希望它们在两个单独的变量中。这是该功能最有意义的地方:

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

To express this in C# you would mark the two parameters with outin the method definition, and return void:

要在 C# 中表达这一点,您需要out在方法定义中标记这两个参数,然后返回void

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

And so to call it:

所以这样称呼它:

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

It's not so nice. Hopefully some future version of C# will allow this:

它不是那么好。希望未来的 C# 版本将允许这样做:

var firstName, lastName = SomeClass.GetInfo();

To enable this, the GetInfomethod would return a Tuple<string, string>. This would be a non-breaking change to the language as the current legal uses of varare very restrictive so there is no valid use yet for the above "multiple declaration" syntax.

要启用此功能,该GetInfo方法将返回一个Tuple<string, string>. 这将是对语言的不间断更改,因为 的当前合法使用var非常严格,因此上述“多重声明”语法尚无有效用途。

回答by ja72

You can do this in C#

你可以在 C# 中做到这一点

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

or you can be fancy like this

或者你可以像这样幻想

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

回答by user1414213562

Update:In C#7 you can easily assign multiple variables at once using tuples. In order to assign array elements to variables, you'd need to write an appropriate Deconstruct()extension methods:

更新:在 C#7 中,您可以使用元组轻松地一次分配多个变量。为了将数组元素分配给变量,您需要编写适当的Deconstruct()扩展方法:

Another way to consume tuples is to deconstruct them. A deconstructing declaration is a syntax for splitting a tuple (or other value) into its parts and assigning those parts individually to fresh variables:

(string first, string middle, string last) = LookupName(id1); // deconstructing declaration
WriteLine($"found {first} {last}.");

In a deconstructing declaration you can use var for the individual variables declared:

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

Or even put a single var outside of the parentheses as an abbreviation:

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

You can also deconstruct into existing variables with a deconstructing assignment:

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

Deconstruction is not just for tuples. Any type can be deconstructed, as long as it has an (instance or extension) deconstructor method of the form:

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

The out parameters constitute the values that result from the deconstruction.

(Why does it use out parameters instead of returning a tuple? That is so that you can have multiple overloads for different numbers of values).

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

It will be a common pattern to have constructors and deconstructors be “symmetric” in this way. https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/

另一种使用元组的方法是解构它们。解构声明是一种将元组(或其他值)拆分为其部分并将这些部分单独分配给新变量的语法:

(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/



Old answer:

旧答案:

In fact, you can achieve similar functionality in C# by using extension methods like this (note: I haven't include checking if arguments are valid):

事实上,您可以通过使用这样的扩展方法在 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]);
}
//...

And you can use them like this:

你可以像这样使用它们:

new[] { "hey", "now" }.Match((str1, str2) =>
{
    Console.WriteLine(str1);
    Console.WriteLine(str2);
});

In case a return value from a function is needed, the following overload would work:

如果需要函数的返回值,以下重载将起作用:

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

In this way:

通过这种方式:

  • You avoid having to repeat array name like in solution proposed by JaredPar and others; the list of "variables" is easy to read.

  • You avoid having to explicitly declare variables types like in Daniel Earwicker's solution.

  • 您不必像 JaredPar 和其他人提出的解决方案那样重复数组名称;“变量”列表很容易阅读。

  • 您不必像 Daniel Earwicker 的解决方案那样显式声明变量类型。

The disadvantage is that you end up with additional code block, but I think it's worth it. You can use code snippets in order to avoid typing braces etc. manually.

缺点是你最终会得到额外的代码块,但我认为这是值得的。您可以使用代码片段以避免手动输入大括号等。

I know it's a 7 years old question, but not so long time ago I needed such a solution - easy giving names to array elements passed into the method (no, using classes/structs instead of arrays wasn't practical, because for same arrays I could need different element names in different methods) and unfortunately I ended up with code like this:

我知道这是一个 7 年前的问题,但不久前我需要这样一个解决方案 - 轻松为传递给方法的数组元素命名(不,使用类/结构而不是数组是不切实际的,因为对于相同的数组我可能需要在不同的方法中使用不同的元素名称),不幸的是我最终得到了这样的代码:

var A = points[0];
var A2 = points[1];
var B = points[2];
var C2 = points[3];
var C = points[4];

Now I could write (in fact, I've refactored one of those methods right now!):

现在我可以写了(事实上,我现在已经重构了其中一种方法!):

points.Match((A, A2, B, C2, C) => {...});


My solution is similar to pattern matching in F# and I was inspired by this answer: https://stackoverflow.com/a/2321922/6659843

我的解决方案类似于 F# 中的模式匹配,我的灵感来自这个答案:https: //stackoverflow.com/a/2321922/6659843

回答by Illuminati

You can use named tuples with C# 7now.

您现在可以在C# 7 中使用命名元组。

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

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