2009-09-14 24 views
14

Kann ich jeden Wert in einem Array zuweisen, um Variablen in einer Zeile in C# zu trennen? Hier ist ein Beispiel in Ruby-Code von dem, was ich will:C# Werte des Arrays einzelnen Variablen in einer Zeile zuweisen

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

Ich bin nicht sicher, ob das, was ich will in C# möglich ist.

Edit: für diejenigen, die vorschlagen, dass ich nur die Zeichenfolgen "hey" und "jetzt" Variablen zuweisen, das ist nicht was ich will. die folgenden Stellen Sie sich vor:

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

Nun ist die Tatsache, dass die Methode get_two_values Strings zurückgegeben „hey“ und „jetzt“ willkürlich ist. In der Tat könnte es zwei beliebige Werte zurückgeben, sie müssen nicht einmal Strings sein.

+3

Wow, hässlich und verwirrend. Erinnert mich an mein letztes Date. – Will

+1

@Will: Wirklich? Ich denke, es ist schön und prägnant, während es immer noch klar und lesbar ist. Ich mag das Feature in Python und benutze es häufig. – Randolpho

+1

Aus einer C# Perspektive, auf jeden Fall. Es sieht so aus, als würden Sie zwei verschiedenen Variablen einen Verweis auf ein einzelnes Array zuweisen ... wie str1 = new string [] {"one", "two"}; str2 = str1; Es ist also sofort verwirrend für C# -Entwickler. Das hässliche bisschen war nur so, dass ich in den Witz passen konnte. – Will

Antwort

12

Dies ist in C# nicht möglich.

Das nächste, was ich denken kann, ist die Initialisierung in der gleichen Zeile zu verwenden, mit indexs

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

Das ist im Grunde, was Rubin unter den Abdeckungen tut; Die Sache, die @ Sarah will, ist im Grunde syntaktischer Zucker. – Randolpho

+0

Ich würde es syntaktisches s-omething nennen. Verdeckt Ruby die Unterschiede zwischen der Speicherzuordnung von Primitiven und Referenztypen ??? – Will

+1

Ruby ist eine Skriptsprache. Es gibt keine primitiven Typen; Sie sind alle auf dem Haufen - Referenztypen. – Randolpho

1

Sie können es in einer Zeile, aber nicht als eine Erklärung.

Zum Beispiel:

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

Python und Ruby unterstützt die Zuordnung, die Sie zu tun versuchen; C# nicht.

2

Ich bin mir nicht sicher, ob was ich will ist in C# möglich.

Es ist nicht.

0

Nein, aber Sie können ein Array von Strings initialisieren:

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

Obwohl das für Sie wahrscheinlich nicht allzu nützlich ist. Ehrlich gesagt ist es nicht schwer, sie auf zwei Linien zu setzen:

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

Der reale Anwendungsfall dafür ist eine bequeme Möglichkeit bietet, um mehrere Werte aus einer Funktion zurückgeben. Es ist also eine Ruby-Funktion, die eine feste Anzahl von Werten im Array zurückgibt, und der Aufrufer will sie in zwei separaten Variablen. Hier wird die Funktion am meisten Sinn macht:

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

dieses # in C Um auszudrücken, würden Sie die beiden Parameter mit out in der Methodendefinition markieren, und das Rück void:

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

Und so ist es zu nennen :

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

Es ist nicht so nett. Hoffentlich einige zukünftige Version von C# wird dies ermöglichen:

var firstName, lastName = SomeClass.GetInfo(); 

Um dies zu ermöglichen, die GetInfo Methode zurückkehren würde eine Tuple<string, string>.Dies wäre eine nicht-brechende Änderung der Sprache, da die derzeitigen legalen Verwendungen von var sehr restriktiv sind, so dass es für die obige "Mehrfachdeklarations" -Syntax noch keine gültige Verwendung gibt.

2

Sie können dies tun, in C#

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

oder Sie können wie diese

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

aktualisieren fancy: In C# 7 können Sie einfach zuweisen mehrere Variablen auf einmal mit Tupeln. Um Array-Elemente Variablen zuweisen, müssen Sie eine geeigneten Deconstruct() Erweiterungsmethoden schreiben:

Eine andere Möglichkeit Tupeln zu konsumieren ist, sie zu dekonstruieren. Eine Dekonstruktion Erklärung ist eine Syntax für ein Tupel Aufspalten (oder einen anderen Wert) in seine Teile und die Teile einzeln an die frische Variablen zuweisen:

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

In einer Dekonstruktion Erklärung können Sie var für die einzelnen Variablen deklariert :

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

oder sogar außerhalb der Klammern als Abkürzung ein einzelnes var setzen:

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

Sie können auch in bestehende Variablen mit einer Dekonstruktion Zuordnung dekonstruieren:

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

Dekonstruktion ist nicht nur für Tupel. Jede Art kann dekonstruiert, solange es ein (instance oder Erweiterung) hat Dekonstruktor Methode der der Form:

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

Die aus Parametern, die Werte darstellen, die von der deconstruction führen.

(Warum verwendet es Parameter, anstatt ein Tupel zurückzugeben? Das ist , so dass Sie mehrere Überladungen für verschiedene Zahlen von Werten haben können).

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

Es wird ein gemeinsames Muster sein Konstrukteuren und deconstructors sein „symmetrisch“ auf diese Weise zu haben. https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/


Alte Antwort:

In der Tat können Sie eine ähnliche Funktionalität in C# erreichen durch Erweiterungsmethoden wie folgt aus (Anmerkung: Ich habe nicht überprüft sind, wenn Argumente gültig sind) :

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]); 
} 
//... 

Und Sie sie wie folgt verwendet werden:

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

Wenn ein Rückgabewert einer Funktion benötigt wird, würde die folgende Überlastung arbeiten:

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

Auf diese Weise:

  • Sie vermeiden, dass wie Array-Namen zu wiederholen, in Lösung vorgeschlagen von JaredPar und anderen; Die Liste der "Variablen" ist leicht zu lesen.

  • Sie vermeiden die explizite Deklaration von Variablentypen wie in Daniel Earwickers Lösung.

Der Nachteil ist, dass Sie mit zusätzlichen Codeblock am Ende, aber ich denke, es lohnt sich. Sie können Code-Snippets verwenden, um zu vermeiden, dass Klammern usw. manuell eingegeben werden.

Ich weiß, es ist eine 7 Jahre alte Frage, aber vor nicht allzu langer Zeit brauchte ich eine solche Lösung - einfach geben Namen an Array-Elemente in die Methode übergeben (nein, mit Klassen/Strukturen anstelle von Arrays war nicht praktisch, weil für gleiche Arrays konnte ich verschiedene Elementnamen in verschiedenen Methoden) benötigen, und leider hatte ich am Ende Code wie folgt auf:

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

jetzt konnte ich (in der Tat schreiben, ich eine dieser Methoden jetzt Refactoring haben!):

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

Meine Lösung ist zu Mustervergleich in F # ähnlich und ich war von dieser Antwort inspiriert: https://stackoverflow.com/a/2321922/6659843

0

Sie jetzt Tupel mit C# 7 Namen verwenden können.

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

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