Несколько параметров в списке в С#. Как создать без класса?
Это, вероятно, довольно очевидный вопрос, но как я могу создать 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 });
Ответы
Ответ 1
Если вы используете .NET 4.0, вы можете использовать Tuple
.
List<Tuple<T1, T2>> list;
Для более старых версий .NET вам необходимо создать собственный класс (если вам не повезло, чтобы найти класс, который соответствует вашим потребностям в библиотеке базового класса).
Ответ 2
Если вы не возражаете, что объекты, подлежащие вымыванию, вы можете использовать класс Tuple, добавленный в .net 4
var list = new List<Tuple<string,int>>();
list.Add(new Tuple<string,int>("hello", 1));
list[0].Item1 //Hello
list[0].Item2 //1
Однако, если вы каждый раз добавляете два элемента, а один из них - уникальный идентификатор, вы можете использовать Dictionary
Ответ 3
При необходимости вы можете использовать словарь, который также является общей коллекцией:
Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("string", 1);
Ответ 4
Только список принимает только один параметр типа.
Самое близкое, что вы получите в списке:
var list = new List<Tuple<string, int>>();
list.Add(Tuple.Create("hello", 1));
Ответ 5
Чтобы добавить к тому, что мне предложили, мне нравится следующая конструкция, чтобы избежать раздражения добавления членов в коллекции keyvaluepair.
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"}};
Мне лично нравится приведенный выше код над более подробными примерами. К сожалению, С# на самом деле не поддерживает типы кортежей изначально, поэтому этот маленький хак творит чудеса.
Если вам действительно нужно больше 2, я предлагаю создать абстракции по типу кортежа. (хотя Tuple
- это класс, а не структура типа KeyValuePair
, это интересное различие).
Как ни странно, синтаксис списка инициализаторов доступен на любом IEnumerable
, и он позволяет использовать любой метод Add
, даже те, которые на самом деле не перечислены вашим объектом. Это очень удобно, если вы хотите добавить элемент object[]
в качестве члена params object[]
.
Ответ 6
Другое решение создает общий список анонимного типа.
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
.
Ответ 7
Как сказал Скотт Чемберлен (и несколько других), Tuples работают лучше всего, если вы не против иметь неизменяемые объекты (то есть только для чтения).
Если, как и предложил Дэвид, вы хотите ссылаться на int на строковое значение, например, вы должны использовать словарь
Dictionary<string, int> d = new Dictionary<string, int>();
d.Add("string", 1);
Console.WriteLine(d["string"]);//prints 1
Если, однако, вы хотите с уверенностью хранить свои элементы в списке и не хотите использовать систему ссылок в стиле словаря, тогда ваш лучший выбор (то есть только реальное решение прямо сейчас) будет заключаться в использовании KeyValuePair, который по существу является 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 элемента), вы просто складываете его. Предоставлено это очень быстро уродливо:
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
Таким образом, очевидно, что если вы должны это сделать, вы должны, вероятно, также определить вспомогательную функцию.
Мой совет: если ваш кортеж содержит более двух элементов, определите свой собственный класс. Вы можете использовать инструкцию typedef-esque, например:
using quad = KeyValuePair<KeyValuePair<int,string>, KeyValuePair<int,string>>;
но это не упрощает создание экземпляров. Вы, вероятно, потратили намного меньше времени на создание параметров шаблона и больше времени на не-шаблонный код, если вы идете с пользовательским классом при работе с кортежами из более чем 2 элементов.
Ответ 8
Для тех, кто хочет использовать класс.
Создайте класс со всеми необходимыми параметрами
Создайте список с классом как параметр
class MyClass
{
public string S1;
public string S2;
}
List<MyClass> MyList= new List<MyClass>();
Ответ 9
Это отлично работает со мной
List<string> myList = new List<string>();
myList.Add(string.Format("{0}|{1}","hello","1") ;
label:myList[0].split('|')[0]
val: myList[0].split('|')[1]