Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there something similar to singletonList in C#

Tags:

c#

Java has Collections.singletonList(T) which returns a List<T> of exactly one element. Is there something similar in C# that returns an IList?

like image 670
Miserable Variable Avatar asked Aug 22 '11 08:08

Miserable Variable


People also ask

What is singletonList?

Description. The singletonList(T) method is used to return an immutable list containing only the specified object.

What is singleton class in Java?

In Java, Singleton is a design pattern that ensures that a class can only have one object. To create a singleton class, a class must implement the following properties: Create a private constructor of the class to restrict object creation outside of the class.


2 Answers

IEnumerable<T> enumerable = Enumerable.Repeat(t, 1);

Creates an IEnumerable with one element.

like image 174
Patrick Avatar answered Oct 12 '22 11:10

Patrick


Array implements IList; and the length cannot be modified via Add (as ReadOnly is true).

Thus, SingletonList<int> could be implemented as easily as:

var slist = new int[] { 5 };

You may want to wrap it in a System.Collections.ObjectModel.ReadOnlyCollection<T> so that the single value cannot be changed (if the Java Singleton list works like this). E.g.

var slist = new System.Collections.ObjectModel.ReadOnlyCollection<int>(new int[] { 5 });

You can also create an extension method.

public static IList<T> AsSingletonList<T>(this IEnumerable<T> source)
{
    foreach (var item in source)
    {
        return new System.Collections.ObjectModel.ReadOnlyCollection<T>(new T[] { item });
    }
    return new System.Collections.ObjectModel.ReadOnlyCollection<T>(new T[] { default(T) });
}

Or one that asserts there is exactly one value in the source:

public static IList<T> AsSingletonList<T>(this IEnumerable<T> source)
{
    IList<T> result = null;
    foreach (var item in source)
    {
        if (result != null)
            throw new ArgumentOutOfRangeException("source", "Source had more than one value.");
        result = new System.Collections.ObjectModel.ReadOnlyCollection<T>(new T[] { item });
    }

    if (result == null)
        throw new ArgumentOutOfRangeException("source", "Source had no values.");
    return result;
}

Edit: Used ReadOnlyCollection<T> to prevent mutation of the single value.

Note: While I think the other answers are correct, the List<T> by default has a capacity of 10 - which is a tiny bit wasteful.

like image 36
Jonathan Dickinson Avatar answered Oct 12 '22 11:10

Jonathan Dickinson