Wildcard equivalente en C # generics

Digamos que tengo una clase genérica de la siguiente manera:

public class GeneralPropertyMap { } 

En alguna otra clase tengo un método que toma una matriz de GeneralPropertyMap . En Java, para tomar una matriz que contenga cualquier tipo de GeneralPropertyMap el método se vería así:

 private void TakeGeneralPropertyMap(GeneralPropertyMap[] maps) { } 

Usamos el comodín para que luego podamos llamar a TakeGeneralPropertyMap pasando un grupo de GeneralPropertyMap con cualquier tipo para T cada uno, como esto:

 GeneralPropertyMap[] maps = new GeneralPropertyMap[3]; maps[0] = new GeneralPropertyMap(); maps[1] = new GeneralPropertyMap(); maps[2] = new GeneralPropertyMap(); //And finally pass the array in. TakeGeneralPropertyMap(maps); 

Estoy tratando de encontrar un equivalente en C # sin éxito. ¿Algunas ideas?

Los generics en C # hacen garantías más fuertes que los generics en Java. Por lo tanto, para hacer lo que quiere en C #, debe permitir que la clase GeneralPropertyMap herede de una versión no genérica de esa clase (o interfaz).

 public class GeneralPropertyMap : GeneralPropertyMap { } public class GeneralPropertyMap { // Only you can implement it: internal GeneralPropertyMap() { } } 

Ahora puedes hacer:

 private void TakeGeneralPropertyMap(GeneralPropertyMap[] maps) { } 

Y:

 GeneralPropertyMap[] maps = new GeneralPropertyMap[3]; maps[0] = new GeneralPropertyMap(); maps[1] = new GeneralPropertyMap(); maps[2] = new GeneralPropertyMap(); TakeGeneralPropertyMap(maps); 

Mientras que, como otros han señalado, no hay correspondencia exacta con los comodines en c #, algunos de sus casos de uso pueden cubrirse con covarianza / contravarianza .

 public interface IGeneralPropertyMap {} // a class can't be covariant, so // we need to introduce an interface... public class GeneralPropertyMap : IGeneralPropertyMap {} // .. and have our class // inherit from it //now our method becomes something like private void TakeGeneralPropertyMap(IList> maps){} // and you can do var maps = new List> { new GeneralPropertyMap(), new GeneralPropertyMap() }; //And finally pass the array in. TakeGeneralPropertyMap(maps); 

La advertencia es que no se puede usar la covarianza con los tipos de valor, por lo que agregar un nuevo GeneralPropertyMap() a nuestra lista falla en el momento de la comstackción.

 cannot convert from 'GeneralPropertyMap' to 'IGeneralPropertyMap' 

Este enfoque puede ser más conveniente que tener una versión no genérica de sus clases / interfaces en caso de que quiera restringir los tipos que puede contener GeneralPropertyMap . En ese caso:

 public interface IMyType {} public class A : IMyType {} public class B : IMyType {} public class C : IMyType {} public interface IGeneralPropertyMap where T : IMyType {} 

te permite tener:

 var maps = new List> { new GeneralPropertyMap(), new GeneralPropertyMap() , new GeneralPropertyMap() }; TakeGeneralPropertyMap(maps); 

No hay equivalente directo a esto en C #.

En C #, esto se haría a menudo si su clase genérica implementara una interfaz o clase base no genérica:

 interface IPropertyMap { // Shared properties } public class GeneralPropertyMap : IPropertyMap { } 

A continuación, podría pasar una serie de estos:

 IPropertyMap[] maps = new IPropertyMap[3]; // ... TakePropertyMap(maps); 

Cree una interfaz entre los miembros de GeneralPropertyMap ( IGeneralPropertyMap ) y luego tome un IGeneralPropertyMap[] como argumento.