webentwicklung-frage-antwort-db.com.de

Mehrere Params in einer Liste in C #. Wie erstelle ich ohne Klasse?

Dies ist wahrscheinlich eine ziemlich offensichtliche Frage, aber wie würde ich eine List erstellen, die mehrere Parameter hat, ohne eine Klasse zu erstellen.

Beispiel:

var list = new List<string, int>();

list.Add("hello", 1);

Normalerweise würde ich eine Klasse so verwenden:

public class MyClass
{
    public String myString {get; set;}
    public Int32 myInt32 {get; set;}
}

dann erstellen Sie meine Liste, indem Sie Folgendes tun:

var list = new List<MyClass>();
list.Add(new MyClass { myString = "hello", myInt32 = 1 });
47
Darcy

Wenn Sie .NET 4.0 verwenden, können Sie eine Tuple verwenden.

List<Tuple<T1, T2>> list;

Für ältere Versionen von .NET müssen Sie eine benutzerdefinierte Klasse erstellen (es sei denn, Sie haben das Glück, eine Klasse zu finden, die Ihren Anforderungen in der Basisklassenbibliothek entspricht).

73
Mark Byers

Wenn Sie nichts dagegen haben, dass die Elemente nicht veränderbar sind, können Sie die Klasse Tuple verwenden, die zu .net 4 hinzugefügt wurde

var list = new List<Tuple<string,int>>();
list.Add(new Tuple<string,int>("hello", 1));

list[0].Item1 //Hello
list[0].Item2 //1

Wenn Sie jedoch jedes Mal zwei Elemente hinzufügen und eines davon eine eindeutige ID ist, können Sie ein Dictionary verwenden.

20

Gegebenenfalls können Sie ein Wörterbuch verwenden, das auch eine generische Sammlung ist:

Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("string", 1);
6
David

List akzeptiert nur einen Typparameter ..__ Das nächste, was Sie mit List erhalten, ist:

 var list = new List<Tuple<string, int>>();
 list.Add(Tuple.Create("hello", 1));
4
Richard Hein

Um das hinzuzufügen, was andere vorgeschlagen haben, gefällt mir das folgende Konstrukt, um zu vermeiden, dass Mitglieder keyvaluepair-Sammlungen hinzugefügt werden.

public class KeyValuePairList<Tkey,TValue> : List<KeyValuePair<Tkey,TValue>>{
    public void Add(Tkey key, TValue value){
        base.Add(new KeyValuePair<Tkey, TValue>(key, value));
    }
}

Dies bedeutet, dass der Konstruktor mit einer besseren Syntax initialisiert werden kann:

var myList = new KeyValuePairList<int,string>{{1,"one"},{2,"two"},{3,"three"}};

Ich persönlich mag den obigen Code über die ausführlicheren Beispiele. Leider unterstützt C # Tuple-Typen nicht wirklich nativ, so dass dieser kleine Hack Wunder wirkt.

Wenn Sie wirklich mehr als 2 benötigen, schlage ich vor, Abstraktionen gegen den Tuple-Typ zu erstellen (obwohl Tuple eine Klasse und keine Struktur wie KeyValuePair ist, ist dies eine interessante Unterscheidung).

Seltsamerweise ist die Syntax der Initialisierungsliste für jede IEnumerable verfügbar, und Sie können jede Add-Methode verwenden, auch wenn diese von Ihrem Objekt nicht tatsächlich aufgezählt werden kann. Es ist sehr praktisch, Dinge wie das Hinzufügen eines object[]-Mitglieds als params object[]-Mitglied zuzulassen.

3
Michael B

Eine andere Lösung generische Liste von anonymen Typen erstellen.

 var list = new[]
 { 
    new { Number = 10, Name = "Smith" },
    new { Number = 10, Name = "John" } 
 }.ToList();

 foreach (var item in list)
 {
    Console.WriteLine(item.Name);
 }

Dies gibt Ihnen auch Unterstützung für intellisense. Ich denke, in einigen Situationen ist es besser als Tuple und Dictionary.

3
stom

Rufen Sie den Schemanamen und den Tabellennamen aus einer Datenbank ab. 

        public IList<Tuple<string, string>> ListTables()
        {

            DataTable dt = con.GetSchema("Tables");

            var tables = new List<Tuple<string, string>>();

            foreach (DataRow row in dt.Rows)
            {
            string schemaName = (string)row[1];
            string tableName = (string)row[2];
            //AddToList();
            tables.Add(Tuple.Create(schemaName, tableName));
            Console.WriteLine(schemaName +" " + tableName) ;
            }
            return tables;
        }
1
aditshh

Wie von Scott Chamberlain (und einigen anderen) bereits gesagt, funktioniert Tuples am besten, wenn es Ihnen nichts ausmacht, unveränderliche (dh schreibgeschützte) Objekte zu haben.

Wenn Sie, wie von David vorgeschlagen, auf das int durch den String-Wert verweisen möchten, sollten Sie ein Wörterbuch verwenden

Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("string", 1);
Console.WriteLine(d["string"]);//prints 1

Wenn Sie Ihre Elemente jedoch veränderlich in einer Liste speichern möchten und kein referenzierendes System im Wörterbuchstil verwenden möchten, ist die beste Wette (dh nur eine echte Lösung) die Verwendung von KeyValuePair std :: pair für C #:

var kvp=new KeyValuePair<int, string>(2, "a");
//kvp.Key=2 and a.Value="a";
kvp.Key = 3;//both key and
kvp.Value = "b";//value are mutable

Natürlich ist dies stapelbar. Wenn Sie also einen größeren Tupel benötigen (wenn Sie 4 Elemente benötigen), stapeln Sie ihn einfach. Zugegeben, das wird sehr schnell hässlich:

     var quad=new KeyValuePair<KeyValuePair<int,string>, KeyValuePair<int,string>>
                (new KeyValuePair<int,string>(3,"a"),
                new KeyValuePair<int,string>(4,"b"));
//quad.Key.Key=3

Wenn Sie dies tun, sollten Sie wahrscheinlich auch eine Hilfsfunktion definieren.

Mein Rat ist, dass, wenn Ihr Tupel mehr als 2 Elemente enthält, Ihre eigene Klasse definiert wird. Sie könnten ein typedef-esque verwenden, indem Sie folgende Anweisung verwenden:

using quad = KeyValuePair<KeyValuePair<int,string>, KeyValuePair<int,string>>;

aber das macht deine instantiierungen nicht einfacher. Sie würden wahrscheinlich viel weniger Zeit mit dem Schreiben von Vorlagenparametern verbringen und mehr Zeit für den Code ohne Boilerplate verwenden, wenn Sie mit einer benutzerdefinierten Klasse arbeiten, wenn Sie mit Tupeln von mehr als 2 Elementen arbeiten

1
rtpg

Für diejenigen, die eine Klasse verwenden möchten.

Erstellen Sie eine Klasse mit allen gewünschten Parametern

Erstellen Sie eine Liste mit der Klasse als Parameter 

class MyClass
        {
            public string S1;
            public string S2;
        }

List<MyClass> MyList= new List<MyClass>();

0
Antonio Leite