2009-12-01 20 views
55

Deseo desarrollar un Método de extensión genérico que debe organizar la secuencia en orden alfabético y luego por orden ascendente longitudinal.¿Cómo crear un método de extensión genérico?

quiero decir

string[] names = { "Jon", "Marc", "Joel", 
        "Thomas", "Copsey","Konrad","Andrew","Brian","Bill"}; 

var query = names.OrderBy(a => a.Length).ThenBy(a => a); 

¿Cuál es la manera de desarrollar Método de extensión genérico?

me trataron:

public static class ExtensionOperation 
    { 
     public static T[] AlphaLengthWise<T>(this T[] names) 
     { 
      var query = names.OrderBy(a => a.Length).ThenBy(a => a); 
      return query; 
     } 
    } 

que recibieron:

de error 1: T no contiene definición para Longitud

Error 2: No se puede convertir System.Linq.IOrderedEnumerable-T[].

+4

por qué debería ser genérico si desea organizar cadenas solamente? – bniwredyc

+6

@bniwredyc ¡Porque 'genérico' suena genial! :) –

+0

Muchas gracias a todos – user215675

Respuesta

80

El primer error se debe a Length es una propiedad de la clase String mientras que en su versión genérica del tipo del parámetro T no se conoce. Podría ser de cualquier tipo.

El segundo error se debe a que devuelve solo el objeto de consulta pero no el resultado real. Es posible que deba llamar al ToArray() antes de regresar.

Con pequeñas modificaciones que podría llegar a esto:

public static class ExtensionOperation 
{ 
    public static IEnumerable<T> AlphaLengthWise<T, L>(
     this IEnumerable<T> names, Func<T, L> lengthProvider) 
    { 
     return names 
      .OrderBy(a => lengthProvider(a)) 
      .ThenBy(a => a); 
    } 
} 

que se podría utilizar como esto:

string[] names = { "Jon", "Marc", "Joel", "Thomas", "Copsey", "Konrad", "Andrew", "Brian", "Bill" }; 
var result = names. AlphaLengthWise(a => a.Length); 
+0

Me encuentro usando técnicas como esta 'longProvider' mucho con código genérico. Es solo una razón más por la que amo mucho a lambdas. : D –

-1

que desea utilizar en lugar de IEnumerable<T>T[]. Aparte de eso, no podrá usar Length de T, ya que no todos los tipos tienen una propiedad Length. Se podría modificar su método de extensión a .OrderBy(a => a.ToString().Length)

Si sabe que siempre le trata con cuerdas, utiliza IEnumerable<String> en lugar de IEnumerable<T>, y podrás acceder a la propiedad Length inmediatamente.

+0

Al cambiar T [] a IEnumerable no se solicitará la propiedad Longitud para los elementos. –

+0

seguro que no. esa parte de la respuesta fue con respecto al segundo error. '' IOrderedEnumerable implementa IEnumerable '' , por lo que habría que resolver una parte del problema. En cuanto a la propiedad 'Longitud ', mi sugerencia fue que' ToString() 'se usara para asegurar una cadena, o, si el nuevo siempre tratara con cadenas, para cambiar' T' por 'string'. –

14

¿Por qué quieres hacer esto genéricamente? Sólo tiene que utilizar

public static class ExtensionOperations 
{ 
    public static IEnumerable<string> AlphaLengthWise(this string[] names) 
    { 
     var query = names.OrderBy(a => a.Length).ThenBy(a => a); 
     return query; 
    } 
} 
+1

¿Por qué 'cadena []' y no 'IEnumerable '? Puede eliminar '.ToArray()' y dejarlo diferido (si no me equivoco). –

2

Quiero desarrollar un método de extensión genérica que debe organizar las cuerdas en alfabético entonces ...

public static class ExtensionOperation 
{ 
    public static IEnumerable<String> AplhaLengthWise(
            this IEnumerable<String> names) 
    { 
     return names.OrderBy(a => a.Length).ThenBy(a => a); 
    } 
} 
3

¿Por qué quiere que sea genérica?

Esto solo funcionará cuando T tenga una propiedad de longitud, y necesitará una interfaz para aplicar eso.

Además T tiene que ser IComparable.

1

Copia cómo Microsoft hace:

public static class ExtensionOperation { 
    // Handles anything queryable. 
    public static IOrderedQueryable<string> AlphaLengthWise(this IQueryable<string> names) { 
     return names.OrderBy(a => a.Length).ThenBy(a => a); 
    } 
    // Fallback method for non-queryable collections. 
    public static IOrderedEnumerable<string> AlphaLengthWise(this IEnumerable<string> names) { 
     return names.OrderBy(a => a.Length).ThenBy(a => a); 
    } 
} 
5

creo que puede ser un poco confuso para el propósito de los genéricos.

genéricos son una manera de adaptar una clase o método para un tipo específico. Un método o clase genérico está diseñado para trabajar con cualquier tipo. Esto se ilustra más fácilmente en la clase List<T>, donde se puede personalizar para que sea una lista de cualquier tipo. Esto le da la seguridad de tipo de saber que la lista solo contiene ese tipo específico.

Su problema está diseñado para funcionar en un tipo específico, el tipo string. Los genéricos no van a resolver un problema que involucra un tipo específico.

Lo que queremos es un simple (no genérico) Método de extensión:

public static class ExtensionOperations 
{ 
    public static IEnumerable<string> AlphaLengthWise(
     this IEnumerable<string> names) 
    { 
     if(names == null) 
      throw new ArgumentNullException("names"); 

     return names.OrderBy(a => a.Length).ThenBy(a => a); 
    } 
} 

Hacer el argumento y el tipo de retorno IEnumerable<string> lo convierte en un método de extensión no genérico que puede aplicarse a cualquier tipo de aplicación de IEnumerable<string>. Esto incluirá string[], List<string>, ICollection<string>, IQueryable<string> y muchos más.

Cuestiones relacionadas