2009-07-08 3 views
16

Es ist mir fast peinlich, diese Frage zu stellen, aber als langjähriger C-Programmierer habe ich das Gefühl, dass mir vielleicht der beste Weg, dies in C# zu tun, nicht bewusst ist.Was ist der beste Weg, um zwei Listen in C# zurückzugeben?

Ich habe eine Member-Funktion, die ich zwei Listen eines benutzerdefinierten Typs (List<MyType>) zurückgeben muss, und ich weiß im Voraus, dass ich immer einen Rückgabewert von nur zwei dieser Listen haben werde.

Die offensichtlichen Optionen sind:

public List<List<MyType>> ReturnTwoLists(); 

oder

public void ReturnTwoLists(ref List<MyType> listOne, ref List<myType> listTwo); 

Beide scheinen nicht optimal.

Haben Sie Vorschläge, wie Sie das verbessern können?

Der erste Weg macht nicht klar in der Syntax, dass nur 2 Listen zurückgegeben werden, und der zweite Weg verwendet Referenzen und dann einen Rückgabewert, die so nicht-C# scheinen.

Antwort

31

Zunächst einmal, dass wahrscheinlich out sein sollte, nicht ref.

Zweitens können Sie einen Typ deklarieren und zurückgeben, der die zwei Listen enthält.

Drittens können Sie eine generische Tuple und geben eine Instanz davon erklären:

class Tuple<T,U> { 
    public Tuple(T first, U second) { 
     First = first; 
     Second = second; 
    } 
    public T First { get; private set; } 
    public U Second { get; private set; } 
} 

static class Tuple { 
    // The following method is declared to take advantage of 
    // compiler type inference features and let us not specify 
    // the type parameters manually. 
    public static Tuple<T,U> Create<T,U>(T first, U second) { 
     return new Tuple<T,U>(first, second); 
    } 
} 

return Tuple.Create(firstList, secondList); 

Sie diese Idee für unterschiedliche Anzahl von Elementen erweitern können.

+7

Nur ein Rest ... .NET 4.0 hat Tuple <> Typ. –

+12

Ich sehe, dass Sie T und U verwendet haben, um die Elemente anzugeben. Wenn Sie mehr als ein 2-Tupel hätten, würden Sie sich für T-U-V-W ... oder T-U-P-L-E entscheiden? :) –

+5

@Mark: habe nicht daran gedacht. Bevor ich darüber nachdenke, würde ich darüber nachdenken, zu F # zu wechseln! –

24

Return dies:

public class MyTwoLists { 
    public List<MyType> ListOne {get;set;} 
    public List<MyType> ListTwo {get;set;} 
} 
0

Erstellen Sie eine einfache Struktur, die beide enthält und als Ausgabe der Funktion zurückgeben?

4

Ihr erster Vorschlag ist nicht zwei Listen. Es ist eine Liste von Listen.

Die zweite Option würde tun, was Sie vorhaben, aber Sie könnten es ändern, um das Schlüsselwort out anstelle von ref zu verwenden, damit die Anrufer Ihrer Methode die Absicht von dem, was Sie tun, wissen.

public void ReturnTwoLists(out List<MyType> listOne, out List<myType> listTwo); 
3

Sie haben ein paar Optionen:

ein Paar verwenden, wenn die Listen, um bedeutungslos sind:

public Pair<List<MyType>,List<MyType> ReturnTwoLists() 
{ 
     return new Pair(new List<MyType(), new List<MyType()); 
} 

Sie können aus oder ref Parameter verwenden, wie Sie erwähnt . Dies ist eine gute Option, wenn eine Liste aussagekräftiger ist als die andere.

Sie einen Wörterbuch verwenden könnten, wenn der Kunde die Schlüssel kennen, oder wollen die Arbeit tun, um sie zu sehen:

public Dictionary<string,List<MyType> ReturnTwoLists() 
{ 
     Dictionary<string,List<MyTpe>> d = new Dictionary<string,List<MyType>>(); 
     d.Add("FirstList",new List<MyType>()); 
     d.Add("SecondList",new List<MyType>()); 
     return new Dictionary()(new List<MyType(), new List<MyType()); 
} 

Oder die „richtige“ Lösung in meinen Augen, auf Vollständigkeit und Konsistenz wäre es, eine einfache Datencontainer-Klasse zu erstellen, die die beiden Listen enthält.Dies liefert einem Verbraucher stark typisierte, gute statisch kompilierte (gelesen: intellisensefähige) Rückgabewerte, mit denen er arbeiten kann. Die Klasse kann direkt neben der Methode verschachtelt werden.

Verwandte Themen