【问题标题】:Shortcut for creating single item list in C#C#中创建单项列表的快捷方式
【发布时间】:2009-01-20 19:44:39
【问题描述】:

在 C# 中,是否有一个内联快捷方式来实例化只有一项的 List

我目前正在做:

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

到处都有这段代码会降低可读性。我想过使用这样的实用方法:

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

所以我可以这样做:

SingleItemList("title");

有没有更短/更干净的方法?

谢谢。

【问题讨论】:

    标签: c#


    【解决方案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", ... };
    

    【讨论】:

    • 在第一个选项的括号中放一个 1 字面量,以便分配一个空间的存储空间,而不是默认的 10
    • 我相信默认值是 4:new List { "Hello" }.Capacity == 4
    【解决方案2】:
    var list = new List<string>(1) { "hello" };
    

    与其他人发布的非常相似,只是它确保最初只为单个项目分配空间。

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

    【讨论】:

    • 容量设置为一。我在这个页面上投了四个答案,包括 Jon Skeet 的两个答案,但我认为这个是最正确的。
    【解决方案3】:

    Michael 使用扩展方法的想法导致了一些更简单的事情:

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

    所以你可以这样做:

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

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

    【讨论】:

    • 我也不确定我是否喜欢它:这不是字符串类型的“奇怪”扩展(例如)吗?
    • 我还没有在你的书中使用扩展方法,Jon :-) 这看起来有点奇怪,但我喜欢它的实用性。谢谢马丁和乔恩。
    • @Martin:这是 every 类型的奇怪扩展。通常不鼓励这样做,但这是一个有趣的一般想法。
    • 它有一些内部特定领域的语言使用,尤其是值类型。举个例子:clock.AlertUser.In(1.Minute) 比 clock.AlertUser(TimeSpan.FromMinutes(1));
    【解决方案4】:

    基于对Google Java Collections 的曝光,与我之前的答案不同:

    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。)

    【讨论】:

      【解决方案5】:
      new[] { "item" }.ToList();
      

      比它短

      new List<string> { "item" };
      

      而且您不必指定类型。

      【讨论】:

        【解决方案6】:

        使用带有方法链的扩展方法。

        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

        【讨论】:

        • 也许这是因为自 2009 年以来 C# 的更新版本,但我发现 new List&lt;string&gt; {"Yes"} 更好......?
        • @ErikE 根据 Microsoft 文档 (msdn.microsoft.com/en-us/library/bb384062(v=vs.90).aspx),这在 Visual Studio 2008 中得到支持。如果我当时过于复杂,我不记得那么久了。更新中。
        【解决方案7】:

        另一种方式,在“C#/.Net Little wonders”上找到(不幸的是,该站点已不存在):

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

        【讨论】:

        • 混乱但聪明。
        【解决方案8】:

        对于 java 中可枚举的单个项目,它将是 Collections.singleton("string");

        在 c# 中,这将比新列表更有效:

        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;
            }
        }
        

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

        【讨论】:

        • 这实际上是我认为的最佳答案。拥有单个项目列表以减少分配大小是一种非常常见的模式。如果您已经在寻找捷径,不妨将方便与好处结合起来。
        【解决方案9】:

        我有这个小功能:

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

        (迟到的答案,但我偶然发现了这个老歌,并认为这可能会有所帮助)

        【讨论】:

          【解决方案10】:

          你也可以这样做

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

          【讨论】:

            【解决方案11】:

            我会做的

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

            【讨论】:

              【解决方案12】:

              试试 var

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

              【讨论】:

                【解决方案13】:

                受到其他答案的启发(因此我可以在需要时随时获取它!),但命名/样式与 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 命名空间的目的是什么?
                • @StephenRobinson 将Lazy 扩展名放在System 中的原因是Lazy 本身在System 中[因此Create 将出现在没有using 的compleiton 列表中]。强迫人们使用open diff 命名空间没有什么好处?将另一件事设为私有不是故意的。固定
                【解决方案14】:

                如果有人登陆此页面并尝试添加对象而不是字符串,那么这对我有用。

                new List<myObj> { new myObj{propertName=propstryValue }
                , new myObj{propertName=propstryValue }, new myObj{propertName=propstryValue }
                };
                

                【讨论】:

                  【解决方案15】:

                  你需要从List&lt;&gt;类创建一个继承者

                      public class SingletonList<T> : List<T>
                      {
                          public SingletonList(T element) : base(1)
                          {
                              this.Add(element);
                          }
                      }
                  

                  您可以使用它来代替基本的List&lt;&gt;

                  var singletonList = new SingletonList<string>("Hello World!");
                  

                  【讨论】:

                    猜你喜欢
                    • 2023-03-28
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-10-12
                    • 2021-12-18
                    • 1970-01-01
                    • 2016-02-23
                    相关资源
                    最近更新 更多