これはおそらくかなり明白な質問ですが、クラスを作成せずに複数のパラメーターを持つ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 });
.NET 4.0を使用している場合は、 Tuple
を使用できます。
List<Tuple<T1, T2>> list;
古いバージョンの.NETの場合、カスタムクラスを作成する必要があります(基本クラスライブラリでニーズに合ったクラスを見つけられるほど幸運でない限り)。
アイテムが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 を使用できます
必要に応じて、汎用コレクションでもある辞書を使用できます。
Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("string", 1);
別のソリューション匿名タイプの汎用リストを作成します。
var list = new[]
{
new { Number = 10, Name = "Smith" },
new { Number = 10, Name = "John" }
}.ToList();
foreach (var item in list)
{
Console.WriteLine(item.Name);
}
これにより、intellisense
のサポートも得られます。状況によっては、Tuple
やDictionary
よりも優れていると思います。
リストは、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型に対する抽象化を作成することをお勧めします(Tuple
はKeyValuePair
のような構造体ではありませんが、これは興味深い違いです)。
不思議なことに、イニシャライザリストの構文はどのIEnumerable
でも使用でき、オブジェクトで実際に列挙できないものであっても、任意のAdd
メソッドを使用できます。 object[]
メンバーをparams object[]
メンバーとして追加することなどを許可すると非常に便利です。
データベースからスキーマ名とテーブル名を取得します。
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;
}
スコット・チェンバレン(および他のいくつか)が言ったように、不変(読み取り専用)オブジェクトを気にしない場合、タプルは最適に機能します。
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つ以上の要素のタプルを操作するときにユーザー定義のクラスを使用する場合、テンプレートパラメーターの記述にかかる時間を大幅に短縮し、非定型コードに多くの時間を費やすでしょう。
クラスを使用したい人向け。
必要なすべてのパラメーターを持つクラスを作成します
クラスをパラメーターとしてリストを作成する
class MyClass
{
public string S1;
public string S2;
}
List<MyClass> MyList= new List<MyClass>();