在C#中创建单个项目列表的快捷方式


134

在C#中,有一个内联快捷方式可以仅用一项实例化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");

有没有更短/更清洁的方法?

谢谢。

Answers:


245

只需使用以下命令:

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

您甚至可以省略()花括号:

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

更新:当然,这也适用于多个条目:

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

5
在第一个选项的括号中放置一个文字,以便分配一个存储空间,而不是默认的10个存储空间
Joel Coehoorn

5
默认值以4结尾,我相信:new List <string> {“ Hello”} .Capacity == 4
Jon Skeet

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

与其他发布的内容非常相似,不同之处在于它确保最初仅为单个项目分配空间。

当然,如果您知道以后要添加一堆东西,这可能不是一个好主意,但仍然值得一提。


容量设置为一。我在本页上对四个答案进行了投票,包括Jon Skeet的两个答案,但我认为这是最正确的答案。
孤独的编码者2014年

28

迈克尔使用扩展方法的想法导致了更简单的事情:

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

因此,您可以这样做:

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

我不确定我是否喜欢它,请注意...


1
我也不确定我是否喜欢:这不是字符串类型的“奇怪”扩展吗(例如)?
M4N

1
乔恩(Jon),我还没有在您的书中提到扩展方法,这似乎有些奇怪,但是我喜欢它的实用性。谢谢马丁和乔恩。
Ryan Ische

2
@马丁:这是每种类型的奇怪扩展。通常不建议这样做,但这是一个有趣的总体思路。
乔恩·斯基特

4
它具有某些内部领域特定的语言用法,尤其是在值类型中。例如:clock.AlertUser.In(1.Minute)的读取效果比clock.AlertUser(TimeSpan.FromMinutes(1))好得多。
Michael Meadows,2009年

17

根据对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”标签-它只是开源版本的“ alpha”,并且基于非常稳定且使用频繁的内部API )



7

将扩展方法与方法链接一起使用。

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/zh-cn/library/bb384062(v=vs.90).aspx


也许这是由于自2009年以来C#的更新,但是我发现new List<string> {"Yes"}更好。
ErikE 2014年

@ErikE根据Microsoft文档(msdn.microsoft.com/en-us/library/bb384062(v=vs.90).aspx),Visual Studio 2008中对此提供了支持。当时我把这个复杂化了。正在更新。
Michael Meadows 2014年

7

在“ C#/。Net小奇迹”上找到的另一种方法(不幸的是,该站点不再存在):

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

令人困惑但很聪明。
PRMan

4

对于Java中可枚举的单个项目,它为Collections.singleton(“ string”);。

在c#中,这将比新的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;
    }
}

但是有没有使用框架的简单方法?


我认为这实际上是最好的答案。具有单个项目列表以减小分配大小是非常常见的模式。如果您已经在寻找捷径,不妨将便利与实用结合起来。
Alex


2

我有这个小功能:

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语句。

(最新答案,但我偶然发现了这首老歌,并认为这可能会有所帮助)



2

受其他答案的启发(因此我可以在需要时随时选择它!),但其命名/样式与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.CreateLazy.Create[2],LazyTask.Create等等:

namespace System.Collections.Generic
{
    public 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);
    }
}

谢谢!我的解决方案也是如此。几件事:(1)您的列表实现不是公共的,因此不能在声明程序集之外使用,以及(2)将这些填充到System名称空间中的目的是什么?
Codure '17

@StephenRobinson放入Lazy扩展名的原因System是它Lazy本身在System[因此Create将出现在补全列表中而没有using]。强迫人们open使用diff名称空间有什么好处?将其他东西设为私有不是故意的;已修复
Ruben Bartelink

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.