Ярлык для создания списка отдельных элементов в С#

В С# есть встроенный ярлык для создания экземпляра List <T> с одним элементом.

Сейчас я делаю:

new List<string>( new string[] { "title" } ))

Наличие этого кода везде снижает читаемость. Я подумал об использовании утилиты вроде этого:

public static List<T> SingleItemList<T>( T value )
{
    return (new List<T>( new T[] { value } ));
}

Так что я мог бы сделать:

SingleItemList("title");

Есть ли более короткий/чистый способ?

Спасибо.

Ответ 1

Просто используйте это:

List<string> list = new List<string>() { "single value" };

Вы можете даже опустить фигурные скобки():

List<string> list = new List<string> { "single value" };

Обновление: конечно, это также работает для нескольких записей:

List<string> list = new List<string> { "value1", "value2", ... };

Ответ 2

var list = new List<string>(1) { "hello" };

Очень похоже на то, что опубликовали другие, за исключением того, что он должен сначала выделить пространство для одного элемента.

Конечно, если вы знаете, что позже будете добавлять кучу вещей, это может быть не очень хорошая идея, но все же стоит упомянуть один раз.

Ответ 3

Идея Майкла об использовании методов расширения приводит к чему-то еще более простому:

public static List<T> InList<T>(this T item)
{
    return new List<T> { item };
}

Так что вы можете сделать это:

List<string> foo = "Hello".InList();

Я не уверен, нравится мне это или нет, заметьте...

Ответ 4

Другой ответ на мой предыдущий, основанный на экспонировании Коллекций Google Java:

public static class Lists
{
    public static List<T> Of<T>(T item)
    {
        return new List<T> { item };
    }
}

Тогда:

List<string> x = Lists.Of("Hello");

Я советую проверить GJC - у него появилось много интересных вещей. (Лично я бы проигнорировал тег "alpha" - это только версия с открытым исходным кодом, которая является "альфа", и она основана на очень стабильной и сильно используемый внутренний API.)

Ответ 5

Используйте метод расширения с цепочкой методов.

public static List<T> WithItems(this List<T> list, params T[] items)
{
    list.AddRange(items);
    return list;
}

Это позволит вам сделать это:

List<string> strings = new List<string>().WithItems("Yes");

или

List<string> strings = new List<string>().WithItems("Yes", "No", "Maybe So");

Обновление

Теперь вы можете использовать инициализаторы списка:

var strings = new List<string> { "This", "That", "The Other" };

См. http://msdn.microsoft.com/en-us/library/bb384062(v=vs.90).aspx

Ответ 6

new[] { "item" }.ToList();

Это меньше

new List<string> { "item" };

и вам не нужно указывать тип.

Ответ 7

Еще один способ, найденный на С#/.NET Little wonders:

Enumerable.Repeat("value",1).ToList()

Ответ 8

У меня есть эта небольшая функция:

public static class CoreUtil
{    
    public static IEnumerable<T> ToEnumerable<T>(params T[] items)
    {
        return items;
    }
}

Так как он не задает конкретный тип возврата, это настолько универсально, что я использую его повсюду. Ваш код будет выглядеть как

CoreUtil.ToEnumerable("title").ToList();

Но, конечно, это также позволяет

CoreUtil.ToEnumerable("title1", "title2", "title3").ToArray();

Я часто использую его, когда мне нужно добавить/добавить один элемент к выходу оператора LINQ. Например, чтобы добавить пустой список в список выбора:

CoreUtil.ToEnumerable("").Concat(context.TrialTypes.Select(t => t.Name))

Сохраняет несколько инструкций ToList() и Add.

(Поздний ответ, но я наткнулся на это старое и подумал, что это может быть полезно)

Ответ 9

Вы также можете сделать

new List<string>() { "string here" };

Ответ 10

Я бы просто сделал

var list = new List<string> { "hello" };

Ответ 11

Для одного элемента, перечислимого в java, это будет Collections.singleton( "string" );

В С# это будет более эффективным, чем новый List:

public class SingleEnumerator<T> : IEnumerable<T>
{
    private readonly T m_Value;

    public SingleEnumerator(T value)
    {
        m_Value = value;
    }

    public IEnumerator<T> GetEnumerator()
    {
        yield return m_Value;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        yield return m_Value;
    }
}

но есть ли более простой способ использования рамки?

Ответ 12

Вдохновленный другими ответами (и поэтому я могу подбирать его каждый раз, когда мне это нужно!), но с именем/стилем, выровненным с F # (который имеет стандартную функцию singleton для каждой структуры данных *):

namespace System.Collections.Generic
{
    public static class List
    {
        public static List<T> Singleton<T>(T value) => new List<T>(1) { value };
    }
}

*, за исключением самого ResizeArray, и, следовательно, этот вопрос:)


На практике я на самом деле называю его Create для согласования с другими помощниками, которые я определяю, например Tuple.Create, Lazy.Create [2 ], LazyTask.Create и т.д.:

namespace System.Collections.Generic
{
    static class List
    {
        public static List<T> Create<T>(T value) => new List<T>(1) { value };
    }
}

[2]

namespace System
{
    public static class Lazy
    {
        public static Lazy<T> Create<T>(Func<T> factory) => new Lazy<T>(factory);
    }
}

Ответ 13

Попробуйте var

var s = new List<string> { "a", "bk", "ca", "d" };