2009-04-16 25 views
12

tengo clase en la que la parte correspondiente se pareceAdición de objeto genérico a la lista genérica en C#

class C { 
    void Method<T>(SomeClass<T> obj) { 
     list.Add(obj); 
    } 
    List<?> list = new List<?>(); 
} 

Cómo debería definir la lista para que compila la clase?

Quiero una lista del tipo List<SomeClass<?>>, que es una lista de objetos de SomeClass donde cada objeto puede tener cualquier parámetro de tipo. La construcción Java ? permite esto; ¿Cuál es el equivalente de C#? Si no existe tal cosa, ¿existe una solución adecuada? (A List<object> haría, pero es terriblemente fea.)

+0

¿Puede por favor explicar el tipo de elementos que esperaría agregar a través de la función "Método"? – el2iot2

+0

ah, no importa, lo veo en un comentario. – el2iot2

+0

En C# 4.0 puede declarar SomeClass como dinámico y no usar los genéricos. La lista se convierte en List . – Goran

Respuesta

13

no creo que usted puede hacer esto en C# ... habría que añadir el parámetro de tipo de la clase:

class C<T> { 
    void Method(SomeClass<T> obj) { 
     list.Add(obj); 
    } 
    List<SomeClass<T>> list = new List<SomeClass<T>>(); 
} 

El otro opción sería usar una interfaz:

+0

Creo que esto se ajusta más al espíritu de lo que entiendo que hace la persona que pregunta (la versión de la interfaz). Básicamente es una lista de elementos "parcialmente conocidos", pero más que simplemente "List " – el2iot2

+1

Gracias por la ayuda. Entonces stackoverflow me permite editar mi pregunta ...pero ¿hay alguna manera de combinar su respuesta con las que se encuentran a continuación que agregan información adicional sobre la imposibilidad de lo que quiero en C#? – errcw

+0

@errcw Puedo editarlo, o cualquier otro con 2k + rep puede ... ¿qué información específica deseaba? –

2

Desafortunadamente, no hay un equivalente directo en C# 3.0 ya que los genéricos son invariables. Podrá hacer algo como esto de una manera elegante utilizando la función de co-contra-varianza segura de C# 4.0. Para solucionarlo, puede heredar SomeClass<T> desde una base no genérica y crear un List<BaseClass> en su lugar. Si cada instancia de la clase debe contener solo un tipo, puede hacer que la clase sea genérica y establecer allí el parámetro de tipo.

+0

Gracias por la punta de BaseClass, realmente útil cuando quiere emular comodines de Java. –

4

Para hacer lo que quiere, tiene dos opciones.

Puede utilizar la lista <objeto> y manejar objetos. Esto no será seguro, y tendrá problemas de boxeo/unboxing para los tipos de valor, pero funcionará.

Su otra opción es utilizar una restricción genérica para limitar a una clase base o interfaz, y utilizar una interfaz >.

2

No sé nada sobre el constructo ? de Java, pero creo que lo siguiente conserva la sintaxis existente al mismo tiempo que coincide con su descripción.

class SomeClass<T> 
    { 
    } 

    class C 
    { 
     void Add<T>(SomeClass<T> item) 
     { 
      Type type = typeof(SomeClass<T>); 
      if (!list.ContainsKey(type)) 
       list[type] = new List<SomeClass<T>>(); 
      var l = (List<SomeClass<T>>)list[type]; 
      l.Add(item); 
     } 

     public void Method<T>(SomeClass<T> obj) 
     { 
      Add(obj); 
     } 
     readonly Dictionary<Type, object> list = new Dictionary<Type, object>(); 
    } 

prueba con lo siguiente:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var c = new C(); 
      var sc1 = new SomeClass<int>(); 
      var sc2 = new SomeClass<String>(); 
      c.Method(sc1); 
      c.Method(sc2); 
      c.Method(sc1); 
      c.Method(sc2); 
     } 
    } 
0

Personalmente, me gustaría hacer esto cuando sea posible; mueve el parámetro genérico del método a la clase.

class C<T> { 
    void Method(SomeClass<T> obj) { 
     list.Add(obj); 
    } 
    List<?> list = new List<?>(); 
} 

Si su lista genérica es miembro, es lógico pensar que la clase debe construirse con esto en mente. Es difícil para nosotros sugerir el mejor patrón sin más contexto de uso para la clase.

Cuestiones relacionadas