2009-01-20 5 views
93

En C#, ¿hay un método abreviado en línea para crear una lista <T> con un solo artículo?Acceso directo para crear una sola lista de elementos en C#

que estoy haciendo actualmente:

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

Tener este código en todas partes reduce la legibilidad. He pensado en el uso de un método de utilidad como esto:

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

Así que podía hacer:

SingleItemList("title"); 

¿Hay un camino más corto/más limpio?

Gracias.

Respuesta

168

Utilice simplemente este:

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

Incluso puede omitir el() aparatos ortopédicos:

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

Actualización: Por supuesto, esto también funciona para más de una entrada:

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

pongo 1 literal entre paréntesis de la primera opción, de modo que se asigna espacio de almacenamiento para exactamente un espacio en lugar del predeterminado 10 –

+4

El valor predeterminado es 4, creo: nueva lista {"Hello"} .Capacity == 4 –

7

Utilice un método de extensión con encadenamiento de métodos.

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

Esto permitirá hacer esto:

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

o

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

actualización

Ahora puede utilizar la lista de inicializadores:

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

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

+0

Tal vez esto se debe a las nuevas versiones de C# desde 2009, pero encuentro 'nueva lista {" Sí "}' para ser mejor ...? – ErikE

+0

@ErikE De acuerdo con la documentación de Microsoft (http://msdn.microsoft.com/en-us/library/bb384062(v=vs.90).aspx) esto fue compatible con Visual Studio 2008. No puedo recordar tan lejos volver para decir definitivamente si sobre-compliqué esto en el momento. Actualizando –

1

También se puede hacer

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

idea de Michael de la utilización de métodos de extensión lleva a algo aún más simple:

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

por lo que podría hacer:

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

no estoy seguro de si te guste o no, fíjate ...

+0

Tampoco estoy seguro de que me guste: ¿no es esta una extensión "extraña" del tipo de cadena (por ejemplo)? – M4N

+1

Todavía no he llegado a los métodos de extensión en su libro, Jon :-) Esto parece extraño, pero me gusta su utilidad. Gracias Martin y Jon. –

+2

@Martin: es una extraña extensión de * cada * tipo. Esto generalmente se desaconseja, pero es una idea general interesante. –

1

me acaba de hacer

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

una respuesta diferente a mi anterior uno, sobre la base de la exposición a la Google Java Collections:

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

continuación:

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

Aconsejo retirar el GJC - tiene muchas cosas interesantes. (Personalmente ignoraría la etiqueta "alpha" - es solo t que la versión de código abierto que es "alfa" y se basa en una API interna muy estable y muy usado.)

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

muy similar a lo que otros han publicado, excepto que se asegura sólo para asignar espacio para el single artículo inicialmente.

Por supuesto, si sabes que agregarás un montón de cosas más adelante, puede que no sea una buena idea, pero vale la pena mencionar una vez.

+0

Capacidad establecida en uno. Voté por cuatro respuestas en esta página, incluidas las de Jon Skeet, pero considero que esta es la más correcta. –

0

Para un solo elemento enumerable en java, sería Collections.singleton ("cadena");

en C# esto va a ser más eficiente que una nueva lista:

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

Pero, ¿existe una manera más sencilla utilizando el marco?

2

Tengo esta pequeña función:

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

Ya que no prescribe un tipo de retorno de concreto esto es tan genérica que lo uso todo el lugar. Su código se vería así

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

Pero por supuesto que también permite

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

A menudo utilizo en cuando tengo que anexar/anteponer un artículo a la salida de una sentencia LINQ. Por ejemplo, para añadir un elemento en blanco a una lista de selección:

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

países algunas declaraciones ToList() y Add.

(respuesta tardía, pero me encontré con este oldie y pensé que esto podría ser útil)

1

Inspirado por las otras respuestas (y por lo que puede recogerlo cuando lo necesito!), Pero con nombres/estilo alineado con F # (que tiene un singleton función estándar por estructura de datos *):

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

* excepto para ResizeArray sí por supuesto, por lo tanto, esta pregunta :)


en la práctica me realidad nombre que Create para alinearse con otros ayudantes defino como Tuple.Create, Lazy.Create [2], etc 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); 
    } 
} 
+0

¡Gracias! Mi solución también. Cosas de pareja: (1) la implementación de su lista no es pública, por lo que no se puede usar fuera del ensamblaje de declaración, y (2) ¿cuál es el propósito de incluir estos elementos en el espacio de nombres del sistema? –

+0

@StephenRobinson razón para poner la extensión 'Lazy' en' System' es que 'Lazy' está en' System' [y por lo tanto 'Create' aparecería en las listas de compleiton sin' using']. No se gana nada al obligar a la gente a 'abrir' un espacio de nombres diff. Hacer que la otra cosa sea privada no fue intencional; fijo –

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

Es más corto que

new List<string> { "item" }; 

y usted no tiene que especificar el tipo.

3

embargo, otra forma, que se encuentra en C#/.Net Little wonders:

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

Confuso pero inteligente. – PRMan

0

Trate var

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