2012-05-18 13 views
5

Tengo un requisito para crear un método estático en mi clase base, pero no me gusta que tenga que declarar los argumentos de tipo, así que me pregunto si voy a hacer esto la manera correcta.Mejor manera de definir el método estático

Básicamente, estoy asignando delegados que asociaré con las propiedades de la clase. Yo podría poner el método en las clases heredadas, así:

public class Foo 
{ 
    public string Property1 { get; set; } 
} 

public class InheritsFoo : Foo 
{ 
    public void AssignDel<TVal>(
     Expression<Func<InheritsFoo, TVal>> expr, 
     Action<InheritsFoo, TVal> action) 
    { 
    } 
} 

O, en una clase de extensión, que podría hacer esto:

public static void AssignDel<T, TVal>(
    this T source, 
    Expression<T, TVal>> expression, 
    Action<T, TVal> action) 
    where T : Foo 
{ 
} 

Ambos me permitiría utilizar AssignDel en una clase instanciada:

var foo = new InheritsFoo(); 
foo.AssignDel(x => x.Property1, handler); 

pero tengo un requisito para hacer AssignDel estática. Esto hace que la extensión sea inútil. Todavía funciona en InheritsFoo, pero realmente quiero mover esto a la clase base. Si lo intento, el argumento de los genéricos no puede inferirse, y tengo que cambiar el uso del método:

InheritsFoo.AssignDel<InheritsFoo, string>(x => x.Property1, handler); 

¿Hay una salida aquí, otra manera de hacer esto que no he pensado?

EDITAR: para tratar el problema en los comentarios sobre si el método de extensión debería funcionar o no ... Fui a la URL a la que hace referencia @Mark M. Resulta que si lo escribo como tal ...

InheritsFoo foo = null; 
foo.AssignDel(x => x.Property1, handler); 

Eso compila (aunque no sé si se ejecutará). Aún así, no piense que califica como usar un método estático, ya que 'foo' todavía se considera una instancia; Una instancia nula, pero una instancia no obstante.

+3

Los métodos de extensión ya son estáticos. ¿Cómo un requisito para hacer que el método sea estático se interponga en el camino de usar métodos de extensión? –

+3

"Tengo un requisito para hacer' AssignDel' estático ". Entonces hazlo estático. –

+1

@Kirk: aunque los métodos de extensión se definen como métodos estáticos, solo se pueden usar como métodos de instancia de la clase prevista. –

Respuesta

0

he conseguido hacer lo que necesitaba simplemente por la aplicación de otro nivel en la cadena de herencia.

public class Foo 
{  
    public string Property1 { get; set; } 
} 

public class Foo<T> : Foo 
{ 
    public static void AssignDel<TVal>(Expression<Func<T, TVal>> expr, Action<T, TVal> action) 
    { } 
} 

public class InheritsFoo : Foo<InheritsFoo> 
{  } 

Puedo tratar InheritsFoo como lo necesito.

1

Pero tengo un requisito para hacer AssignDel estático. Esto hace que la extensión de la sea inútil. Todavía funciona en InheritsFoo, pero Realmente quiero mover esto a la clase base. Si lo intento, el argumento de los genéricos no puede deducirse, y tengo que cambiar el uso del método :

esto no tiene mucho sentido.

InheritsFoo.AssignDel es un método estático.

Llamar a dicho método estático haciendo InheritsFoo.AssignDel<InheritsFoo, string>(x => x.Property1, handler); parece que cumple con sus requisitos.

No entiendo qué está mal con la segunda opción que se te ocurrió. Hace lo que necesita hacer, está claro lo que está sucediendo, ¿es realmente porque pasa InheritsFoo y string en lugar de foo.AssignDel(x => x.Property1, handler);?

Parece que simplemente puede hacer lo siguiente y lograr lo que desea.

public class Foo 
    { 
     public string Property1 { get; set; } 
    } 

    public class InheritsFoo : Foo 
    { 
     public static void AssignDel<TVal>(
      Expression<Func<InheritsFoo, TVal>> expr, 
      Action<InheritsFoo, TVal> action) 
     { 
     } 
    } 

Debo estar perdiendo algo porque parecería que lo utilizaría InheritsFoo.AssignDel(x => x.Property1, handler); que es exactamente lo que quiere.

+0

Especificar los argumentos genéricos funciona, pero es más detallado de lo que sería preferido, especialmente en el caso del argumento de tipo TVal. Es por eso que estoy pidiendo alternativas. – Random

1

El método de extensión ya es estático.

Suponiendo que tienes que lo use en la forma método de extensión, esto debería funcionar:

InheritsFoo.AssignDel(x => x.Property1, handler); 

De la misma manera el compilador infere los parámetros de tipo para la forma de método de extensión, lo hará para la edad de moda estática.

Si usted necesita tener el método con dos paremeters tipo, se podría crear una clase genérica para esto:

public class Foo<T> where T : Foo { 

    public void AssignDel<TVal>(Expression<Func<T, TVal>> expr, Action<T, TVal> action) 
    { 
     //... 
    } 
} 

En este caso, se podría hacer:

Foo<InheritFoo>.AssignDel(x => x.PropertyFromInheritFoo, handler); 

Como se puede mira, solo tienes que declarar un parámetro de tipo, el otro está siendo inferido.

creo que sirve

+0

Esto funcionará si guardo el método en InheritsFoo, cuando me gustaría moverlo a la clase Foo base. – Random

+0

¡Oh! Tengo el problema al que te enfrentas. Parece que eres un tornillo :( – ivowiblo

+0

Entonces ... déjame ver si entendí: ¿Quieres tener el método en la clase Foo y aceptar propiedades para toda la jerarquía? – ivowiblo

Cuestiones relacionadas