2010-06-30 10 views
6

he visto algunos ejemplos en los que transforman una llamada como¿Cuál es la ventaja de usar una llamada a generic-where-clause sobre una llamada no genérica?

void Add(IDrawing item); 

en

void Add<TDrawing>(TDrawing item) where TDrawing : IDrawing; 

lado engañando al intelisense en mostrar el nombre de su clase en lugar del nombre de la interfaz cuando se llama a la función, debido al uso de tipos inferidos en C# 4, ¿hay alguna otra ventaja al usar el segundo enfoque?

Para responder Jon Skeet, el código utilizado nuestro programador es:

public ObservableCollection<IDrawing> Items { get; private set; } 

public void Add<TDrawing>(TDrawing item) where TDrawing : IDrawing 
{ 
    this.Items.Add(item); 
} 

no veo ninguna ventaja en este caso para el uso de un genérico en lugar de usar un parámetro del tipo IDrawing. Supongo que debe haber algún caso donde sea muy apropiado. Tenía curiosidad por ver si me estaba perdiendo algo.

+0

"Además de engañar al intellisense para que muestre el nombre de tu clase" ... maldición, no me di cuenta de que eso sería suficiente, eso es motivo suficiente para querer utilizar el segundo enfoque. – heisenberg

+0

Nota secundaria: el término .NET es "genéricos"; son bastante diferentes a las "plantillas" de C++ o T4. –

+1

Actualizado para usar genéricos. Lo siento, los viejos son viejos. –

Respuesta

5

Realmente depende de lo que sucede en otra parte de la implementación. He aquí un ejemplo diferente:

void Add<TDrawing>(TDrawing item, IList<TDrawing> list) 
    where TDrawing : IDrawing 
{ 
    if (item.SomePropertyOfIDrawing) 
    { 
     list.Add(item); 
    } 
} 

Ahora usted no quiere tomar una IList<IDrawing> aquí - porque entonces no podría utilizarlo si has tenido una List<Painting> por ejemplo ... mientras que con la versión genérica anterior, es absolutamente bien para TDrawing ser Painting: la restricción asegura que la propiedad está disponible para la condición if, y el hecho de que es genérico le permite agregar el elemento de forma segura a la lista.

Si tiene completos ejemplos en los que no cree que hay un beneficio, valdría la pena presentarlos específicamente.

EDITAR: No, en el ejemplo exacto dado ahora no hay ninguna ventaja en hacer que sea un método genérico.

+0

De hecho. Mucho más útil en el nivel de una clase genérica, de modo que toda la clase tenga conocimiento de tipo basado en las restricciones genéricas. –

+0

Sin embargo, eso agrega algo al ejemplo original (la necesidad de mantener ambos parámetros del mismo tipo) ... el ejemplo análogo al original no se limitaría a cambiar a IList , sino también a volver a arrastrar el elemento al elemento IDrawing. Quiero decir, es interesante y todo, pero realmente no responde lo que está preguntando. – heisenberg

+0

@kekekela: Originalmente no había suficiente contexto. Ahora hay un ejemplo más completo, es más fácil de responder. –

1

parece este escenario:

void Add<TDrawing>(TDrawing item, Func<TDrawing, bool> func) 
{ 
    //implementation 
} 

Ahora cuando se llama a este método, en tiempo de compilación, podrás acceder a los proeprties específicas del TDrawing específica que se pasa en este método a utilizar con el Func .

Add<MyDrawing>(drawing, m => m.SomeMyDrawingProp); 
0

La semántica de la versión con la cláusula "where" puede ser muy diferente de la que no tiene cuando se pasa una estructura como parámetro. Las ubicaciones de almacenamiento (incluidos los parámetros) de los tipos de interfaz contienen referencias de objetos de montón. La coerción de tipo de una estructura que implementa una interfaz a una ubicación de almacenamiento de ese tipo de interfaz creará un nuevo objeto de montón con los mismos campos y métodos que la estructura, copiará todos los contenidos de campo (públicos y privados) a ese nuevo objeto y luego almacenará una referencia a ese objeto en la ubicación de almacenamiento. Por el contrario, copiar una estructura a otra ubicación de almacenamiento de ese tipo de estructura copiará todos los campos (públicos y privados) pero dejará el resultado como una estructura, en lugar de un objeto de pila.

Cuestiones relacionadas