web-dev-qa-db-ja.com

C#のリスト内の複数のパラメーター。クラスなしで作成する方法は?

これはおそらくかなり明白な質問ですが、クラスを作成せずに複数のパラメーターを持つListを作成するにはどうすればよいでしょうか。

例:

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

list.Add("hello", 1);

通常、次のようなクラスを使用します。

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

次に、以下を実行してリストを作成します。

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

.NET 4.0を使用している場合は、 Tuple を使用できます。

List<Tuple<T1, T2>> list;

古いバージョンの.NETの場合、カスタムクラスを作成する必要があります(基本クラスライブラリでニーズに合ったクラスを見つけられるほど幸運でない限り)。

76
Mark Byers

アイテムがimutableであることを気にしない場合は、.net 4に追加された Tuple クラスを使用できます。

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

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

ただし、毎回2つのアイテムを追加し、そのうちの1つが一意のIDである場合は、 Dictionary を使用できます

22

必要に応じて、汎用コレクションでもある辞書を使用できます。

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

別のソリューション匿名タイプの汎用リストを作成します。

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

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

これにより、intellisenseのサポートも得られます。状況によっては、TupleDictionaryよりも優れていると思います。

5
stom

リストは、1つの型パラメーターのみを受け入れます。リストで最も近いものは次のとおりです。

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

他の提案に追加するために、キーバリューペアコレクションにメンバーを追加するという煩わしさを避けるために、次の構成が好きです。

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

これが意味することは、コンストラクターをより良い構文で初期化できることです::

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

私は個人的に、より冗長な例よりも上記のコードが好きです。残念ながら、C#はネイティブにTuple型を実際にサポートしていないため、この小さなハックは驚異的に動作します。

本当に2つ以上必要な場合は、Tuple型に対する抽象化を作成することをお勧めします(TupleKeyValuePairのような構造体ではありませんが、これは興味深い違いです)。

不思議なことに、イニシャライザリストの構文はどのIEnumerableでも使用でき、オブジェクトで実際に列挙できないものであっても、任意のAddメソッドを使用できます。 object[]メンバーをparams object[]メンバーとして追加することなどを許可すると非常に便利です。

3
Michael B

データベースからスキーマ名とテーブル名を取得します。

        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

スコット・チェンバレン(および他のいくつか)が言ったように、不変(読み取り専用)オブジェクトを気にしない場合、タプルは最適に機能します。

Davidが提案したように、たとえば文字列値でintを参照したい場合は、辞書を使用する必要があります

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

ただし、要素をリストに変更可能に格納し、辞書スタイルの参照システムを使用したくない場合、最善の策(つまり、現在の唯一の解決策)は、本質的にKeyValuePairを使用することです。 C#のstd :: pair

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

もちろん、これはスタック可能であるため、より大きなタプルが必要な場合(4つの要素が必要な場合など)、スタックするだけです。確かにこれは非常に速くgetsくなります:

     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

したがって、明らかにこれを行う場合は、おそらく補助関数も定義する必要があります。

私のアドバイスは、タプルに3つ以上の要素が含まれる場合、独自のクラスを定義することです。次のようなステートメントを使用してtypedef-esqueを使用できます。

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

しかし、それはあなたのインスタンス化を簡単にするものではありません。 3つ以上の要素のタプルを操作するときにユーザー定義のクラスを使用する場合、テンプレートパラメーターの記述にかかる時間を大幅に短縮し、非定型コードに多くの時間を費やすでしょう。

1
rtpg

クラスを使用したい人向け。

必要なすべてのパラメーターを持つクラスを作成します

クラスをパラメーターとしてリストを作成する

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

List<MyClass> MyList= new List<MyClass>();
0
Antonio Leite