[c#] Pasar un solo elemento como IEnumerable <T>



Answers

Bueno, si el método espera un IEnumerable , debe pasar algo que es una lista, incluso si contiene un solo elemento.

paso

new T[] { item }

como el argumento debería ser suficiente, creo

Question

¿Existe una forma común de pasar un único elemento de tipo T a un método que espera un IEnumerable<T> ? Language es C #, versión de framework 2.0.

Actualmente estoy usando un método de ayuda (es .NET 2.0, así que tengo un montón de métodos de ayuda de lanzamiento / proyección similares a LINQ), pero esto parece tonto:

public static class IEnumerableExt
{
    // usage: IEnumerableExt.FromSingleItem(someObject);
    public static IEnumerable<T> FromSingleItem<T>(T item)
    {
        yield return item; 
    }
}

Otra forma sería, por supuesto, crear y completar una List<T> o una Array y pasarla en lugar de IEnumerable<T> .

[Editar] Como un método de extensión podría llamarse:

public static class IEnumerableExt
{
    // usage: someObject.SingleItemAsEnumerable();
    public static IEnumerable<T> SingleItemAsEnumerable<T>(this T item)
    {
        yield return item; 
    }
}

¿Me estoy perdiendo de algo?

[Edit2] Encontramos que someObject.Yield() (como @Peter se sugiere en los comentarios a continuación) es el mejor nombre para este método de extensión, principalmente por brevedad, por lo que aquí está junto con el comentario XML si alguien quiere obtenerlo:

public static class IEnumerableExt
{
    /// <summary>
    /// Wraps this object instance into an IEnumerable&lt;T&gt;
    /// consisting of a single item.
    /// </summary>
    /// <typeparam name="T"> Type of the object. </typeparam>
    /// <param name="item"> The instance that will be wrapped. </param>
    /// <returns> An IEnumerable&lt;T&gt; consisting of a single item. </returns>
    public static IEnumerable<T> Yield<T>(this T item)
    {
        yield return item;
    }
}



Estoy de acuerdo con los comentarios de @EarthEngine en la publicación original, que es que 'AsSingleton' es un nombre mejor. Vea esta entrada de wikipedia . Luego se deduce de la definición de singleton que si se pasa un valor nulo como argumento, 'AsSingleton' debería devolver un IEnumerable con un único valor nulo en lugar de un IEnumerable vacío que resolvería la if (item == null) yield break; debate. Creo que la mejor solución es tener dos métodos: 'AsSingleton' y 'AsSingletonOrEmpty'; donde, en caso de que se pase un nulo como argumento, 'AsSingleton' devolverá un único valor nulo y 'AsSingletonOrEmpty' devolverá un IEnumerable vacío. Me gusta esto:

public static IEnumerable<T> AsSingletonOrEmpty<T>(this T source)
{
    if (source == null)
    {
        yield break;
    }
    else
    {
        yield return source;
    }
}

public static IEnumerable<T> AsSingleton<T>(this T source)
{
    yield return source;
}

Entonces, estos serían, más o menos, análogos a los métodos de extensión "Primero" y "Primero por defecto" en IEnumerable que se siente bien.




IanG tiene una buena publicación sobre el tema , sugiriendo EnumerableFrom() como el nombre y menciona que la discusión señala que Haskell y Rx lo llaman Return . IIRC F # lo llama Retorno también . F # ' Seq llama al operador singleton<'T> .

Tentador si estás preparado para ser C # -centric es llamarlo Yield [aludiendo al yield return involucrado al realizarlo].

Si le interesan los aspectos del rendimiento, James Michael Hare tiene también una devolución de cero o una publicación que vale la pena escanear.




Este método de ayuda es trabajos para artículos o muchos.

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



La manera más fácil que diría sería una new T[]{item}; ; no hay sintaxis para hacer esto. El equivalente más cercano que puedo pensar es la palabra clave params , pero, por supuesto, eso requiere que tengas acceso a la definición del método y solo se puede usar con matrices.




En C # 3 (sé que dijiste 2), puedes escribir un método de extensión genérico que podría hacer que la sintaxis sea un poco más aceptable:

static class IEnumerableExtensions
{
    public static IEnumerable<T> ToEnumerable<T>(this T item)
    {
        yield return item;
    }
}

El código del cliente es entonces item.ToEnumerable() .




O bien (como se dijo anteriormente)

MyMethodThatExpectsAnIEnumerable(new[] { myObject });

o

MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(myObject, 1));

Como nota al margen, la última versión también puede ser agradable si desea una lista vacía de un objeto anónimo, por ejemplo

var x = MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(new { a = 0, b = "x" }, 0));





Related