2011-06-07 12 views

Respuesta

8

con los genéricos, puede agregar una restricción que significa que el tipo genérico suministrado debe cumplir algunas condiciones, por ejemplo:

  • where T : new() - T debe tener un constructor sin parámetros pública (o ser un struct)
  • where T : class-T debe ser una referencia de tipo (class/interface/delegate)
  • where T : struct-T debe haber un tipo de valor (otro que Nullable<TSomethingElse>)
  • where T : SomeBaseType-T debe ser heredado de SomeBaseType (o SomeBaseType sí mismo)
  • where T : ISomeInterface - T deben implementar ISomeInterface

por ejemplo:

public void SomeGenericMethod<T>(T data) where T : IEnumerable { 
    foreach(var obj in data) { 
     .... 
    } 
} 

es SomeBaseType y ISomeInterface que son interesantes aquí, ya que te permiten exigir (y usar) func ciones definidas en esos tipos; por ejemplo, where T : IList le da acceso a Add(...) etc. ¡SIN EMBARGO!simplemente: no hay tal mecanismo para cosas como:

  • constructores con parámetros
  • métodos estáticos
  • operadores/conversiones
  • métodos arbitrarios no se definen a través de un tipo de base o interfaz

así que no puede solicitarlos, y no puede usarlos (excepto a través de la reflexión). Para algunos de esos dynamic se puede utilizar, sin embargo.

+0

buena explicación. – Idrees

1

No es posible tener:

public interface IInterface { 
    static void Method(); 
} 

Esto se debe a que no está permitido/capaz de limitar la aplicación de las clases para ser métodos estático.

+0

Pero esto genera el mensaje de error 'El modificador 'estático' no es válido para este elemento' –

+0

@James Wiseman," No es posible tener: "se establece desde el principio ... – Lucero

+0

@Lucero - Se fue probablemente un poco desaprensivo, pero mi punto fue que esto genera un mensaje diferente al que se le pregunta. La respuesta tampoco responde a la inferencia de restricciones genéricas en la pregunta original. :-) –

6

así, básicamente:

public class A{} 

public class B{ 
    public static void Foo() {} 
} 

no se puede escribir una limitación genérica para T en:

public class C<T> {} 

De tal manera que se restringe a aceptar solamente A o B en base a la presencia o no -presencia del método estático Foo().

+0

La primera parte de su respuesta es simplemente excelente. La segunda parte es simplemente confusa. _No lo explique si no está allí_. – Idrees

+0

@Idrees - punto justo; se han deshecho :) –

3

Imagine el siguiente código no funciona:

interface IWithStatic 
{ 
    void DoIt(); // non-static 
    static void DoItStatic(); // static 
} 

class C1 : IWithStatic 
{ 
    void DoIt() {} // non-static 
    static void DoItStatic(){} // static 
} 

class C2 : IWithStatic 
{ 
    void DoIt() {} // non-static 
    static void DoItStatic(){} // static 

} 

Y, en un programa:

IWithStatic myObj = GetWithAnyMethod(); // Return a C1 or C2 instance 

myObj.DoIt(); // working, as the runtime type is used (either C1 or C2); 

pero con la estática ... ¿cómo puede el compilador interpretar esto:

IWithStatic.DoItStatic(); // Not knowing which type to use 

¿Ves cuál es el problema ahora?

+0

En realidad, lo siento. – Idrees

+0

Una interfaz define un contrato que una clase debe respetar. Este contrato permite a los consumidores de la clase trabajar con variables declaradas con el tipo de interfaz, no con la implementación real. La implementación real se determina en tiempo de ejecución. Se garantiza que el código de consumo tenga disponible el método llamado. todo esto puede funcionar porque el tiempo de ejecución tiene una instancia para trabajar. Si trabaja con métodos estáticos, no tiene una variable para verificar el tipo en tiempo de ejecución. El compilador no tiene manera de determinar si es C1.DoItStatic o C2.DoItStatic para llamar al –

+0

Ahora lo veo. Gracias +1 – Idrees

Cuestiones relacionadas