157

In C#, is there an inline shortcut to instantiate a List<T> with only one item.

I'm currently doing:

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

Having this code everywhere reduces readability. I've thought of using a utility method like this:

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

So I could do:

SingleItemList("title");

Is there a shorter / cleaner way?

Thanks.

jamesh
  • 19,407
  • 13
  • 55
  • 96
Ryan Ische
  • 3,306
  • 3
  • 20
  • 20

15 Answers15

285

Simply use this:

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

You can even omit the () braces:

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

Update: of course this also works for more than one entry:

List<string> list = new List<string> { "value1", "value2", ... };
M4N
  • 92,565
  • 45
  • 215
  • 258
52
var list = new List<string>(1) { "hello" };

Very similar to what others have posted, except that it makes sure to only allocate space for the single item initially.

Of course, if you know you'll be adding a bunch of stuff later it may not be a good idea, but still worth mentioning once.

Joel Coehoorn
  • 380,066
  • 110
  • 546
  • 781
  • Capacity set to one. I voted for four answers on this page including both of Jon Skeet's but I consider this one to be the most correct. – The Lonely Coder Dec 09 '14 at 14:51
36

Michael's idea of using extension methods leads to something even simpler:

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

So you could do this:

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

I'm not sure whether I like it or not, mind you...

Jon Skeet
  • 1,335,956
  • 823
  • 8,931
  • 9,049
  • 1
    I'm also not sure I like it: isn't this a "strange" extension of the string type (for example) ? – M4N Jan 20 '09 at 19:56
  • 1
    I haven't made it to extension methods in your book yet, Jon :-) This does seems sort of strange, but I like the utility of it. Thanks Martin and Jon. – Ryan Ische Jan 20 '09 at 20:08
  • 3
    @Martin: It's a strange extension of *every* type. This is generally discouraged, but it's an interesting general idea. – Jon Skeet Jan 20 '09 at 20:10
  • 5
    It hase some internal domain specific language uses, especially with value types. Take for example: clock.AlertUser.In(1.Minute) reads much better than clock.AlertUser(TimeSpan.FromMinutes(1)); – Michael Meadows Jan 20 '09 at 20:19
18

A different answer to my earlier one, based on exposure to the Google Java Collections:

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

Then:

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

I advise checking out the GJC - it's got lots of interesting stuff in. (Personally I'd ignore the "alpha" tag - it's only the open source version which is "alpha" and it's based on a very stable and heavily used internal API.)

Jon Skeet
  • 1,335,956
  • 823
  • 8,931
  • 9,049
14
new[] { "item" }.ToList();

It's shorter than

new List<string> { "item" };

and you don't have to specify the type.

8

Yet another way, found on "C#/.Net Little wonders" (unfortunately, the site doesn't exist anymore):

Enumerable.Repeat("value",1).ToList()
Grzegorz Sławecki
  • 1,677
  • 15
  • 27
8

Use an extension method with method chaining.

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

This would let you do this:

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

or

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

Update

You can now use list initializers:

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

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

Michael Meadows
  • 26,946
  • 4
  • 46
  • 60
  • Maybe this is due to newer versions of C# since 2009, but I find `new List {"Yes"}` to be better... ? – ErikE Jul 18 '14 at 00:02
  • @ErikE According to Microsoft documentation (http://msdn.microsoft.com/en-us/library/bb384062(v=vs.90).aspx) this was supported in Visual Studio 2008. I can't remember that far back to say definitively if I over-complicated this at the time. Updating. – Michael Meadows Dec 11 '14 at 18:30
5

For a single item enumerable in java it would be Collections.singleton("string");

In c# this is going to be more efficient than a new 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;
    }
}

but is there a simpler way using the framework?

Squirrel
  • 1,325
  • 2
  • 16
  • 25
  • That's actually the best answer in my opinion. It is a very common pattern to have a single item list, to reduce allocation size. If you are already looking for a shortcut you might as well combine the convenient with the good. – Alexander Oh Mar 09 '20 at 10:12
3

I've got this little function:

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

Since it doesn't prescribe a concrete return type this is so generic that I use it all over the place. Your code would look like

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

But of course it also allows

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

I often use it in when I have to append/prepend one item to the output of a LINQ statement. For instance to add a blank item to a selection list:

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

Saves a few ToList() and Add statements.

(Late answer, but I stumbled upon this oldie and thought this could be helpful)

Gert Arnold
  • 100,019
  • 29
  • 193
  • 278
2

Inspired by the other answers (and so I can pick it up whenever I need it!), but with naming/style aligned with F# (which has a standard singleton function per data structure*):

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

* except for ResizeArray itself of course, hence this question :)


In practice I actually name it Create to align with other helpers I define such as Tuple.Create, Lazy.Create[2], LazyTask.Create etc:

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);
    }
}
Ruben Bartelink
  • 57,716
  • 25
  • 179
  • 233
  • Thanks! My solution as well. Couple things: (1) your list implementation is not public, so it can't be used outside the declaring assembly, and (2) what is the purpose of stuffing these into the System namespace? – Codure Apr 04 '17 at 15:43
  • @StephenRobinson reason for putting the `Lazy` extension in `System` is that `Lazy` itself is in `System` [and hence `Create` would appear in the compleiton lists without a `using`]. There's nothing to be gained from forcing people to `open` a diff namespace? Making the other thing private was not intentional; fixed – Ruben Bartelink Apr 06 '17 at 13:12
2

Try var

var s = new List<string> { "a", "bk", "ca", "d" };
Maher Abuthraa
  • 16,698
  • 10
  • 75
  • 102
delwasaf ewrew
  • 467
  • 1
  • 7
  • 16
2

You can also do

new List<string>() { "string here" };
Rune Grimstad
  • 34,770
  • 10
  • 60
  • 75
2

I would just do

var list = new List<string> { "hello" };
Brian Rasmussen
  • 112,408
  • 34
  • 217
  • 309
0

If someone landed on this page and trying to add object instead of string, then this worked for me.

new List<myObj> { new myObj{propertName=propstryValue }
, new myObj{propertName=propstryValue }, new myObj{propertName=propstryValue }
};
Ali
  • 833
  • 11
  • 34
-1

You need to create an inheritor from the List<> class

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

and you can use it instead of the base List<> class

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