2011-07-01 13 views
31

Tengo una pareja de clases del modelo, así:Cómo añadir atributos a las propiedades de una clase base

public class MyModelBase 
{ 
    public string Name { get; set; } 
} 

public class MyModel : MyModelBase 
{ 
    public string SomeOtherProperty { get; set; } 
} 

¿Cómo se puede añadir un atributo MyModel [Obligatorio] Nombre de la propiedad?

+0

¿Está preguntando sobre las anotaciones de datos? Si no, entonces ¿qué atributo '[Required]' estás preguntando? –

Respuesta

26

Intente utilizar una clase de metadatos. Es una clase separada a la que se hace referencia utilizando atributos que le permiten agregar anotaciones de datos a las clases de modelos de forma indirecta.

p. Ej.

[MetadataType(typeof(MyModelMetadata))] 
public class MyModel : MyModelBase { 
    ... /* the current model code */ 
} 


internal class MyModelMetadata { 
    [Required] 
    public string Name { get; set; } 
} 
+0

¿A alguien le importa comentar sobre el voto a favor? Técnicamente esto me parece correcto (incluso agregó algo similar a mi respuesta original). –

+1

Supongo que esto solo funciona para los atributos en el espacio de nombres DataAnnotaciones y, por lo tanto, no es una solución genérica. – Marchy

+2

[MSDN] (https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx) dice que ** MyModel ** debe ser parcial. –

27

declarar la propiedad de la clase de los padres como virtual:

public class MyModelBase 
{ 
    public virtual string Name { get; set; } 
} 

public class MyModel : MyModelBase 
{ 
    [Required] 
    public override string Name { get; set; } 

    public string SomeOtherProperty { get; set; } 
} 

o puede utilizar un MetadataType para manejar la validación (siempre y cuando usted está hablando de DataAnnotations ... de lo contrario' re atascado con el ejemplo anterior):

class MyModelMetadata 
{ 
    [Required] 
    public string Name { get; set; } 

    public string SomeOtherProperty { get; set; } 
} 

[MetadataType(typeof(MyModelMetadata))] 
public class MyModel : MyModelBase 
{ 
    public string SomeOtherProperty { get; set; } 
} 
+1

Este es el camino a seguir si tiene un comportamiento adicional que no desea perder. +1 – Yuck

+0

Ahora debe tener cuidado con posibles llamadas virtuales en el constructor base. – nicodemus13

+3

De acuerdo con [MSDN] (https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx) ** MyModel ** debe ser parcial. –

8

Noto que ninguna de estas respuestas llama realmente a la propiedad del Nombre base correctamente. La anulación debe escribir algo como lo siguiente, para que no tenga un valor separado para la nueva propiedad.

public class MyModelBase 
{ 
    public virtual string Name { get; set; } 
} 

public class MyModel : MyModelBase 
{ 
    [Required] 
    public override string Name { get { return base.Name; } set { base.Name = value; } 

    public string SomeOtherProperty { get; set; } 
} 
+0

No puedo ver, ¿por qué sería necesario? Si lo que dices es cierto, este código no debería funcionar, pero funciona: http://csharppad.com/gist/c5db27fb3b90f961a2da. Supongo que ese compilador maneja las propiedades automáticas anuladas automáticamente. – Spook

+0

@Spook Creo que sería necesario solo si tiene alguna implementación personalizada en la clase base (como RaisePropertyChanged en setter). Si solo usa propiedades automáticas en la subclase, no se llamará al getter/setter en la clase base. – Ryan

0

Puede sobrecargar la propiedad base con la palabra clave "nueva".

public class MyModelBase 
{ 
    public string Name { get; set; } 
} 

public class MyModel : MyModelBase 
{ 
    [Required] 
    public new string Name {get; set;} 
    public string SomeOtherProperty { get; set; } 
} 
+0

Votación a cambio de qué? – ahmet

+1

Esto "funciona" pero rompe el polimorfismo. Si escribe el siguiente código, "algo" sería nulo. MyModel m = new MyModel(); m.Name = "Blah"; MyModelBase mb = m; var something = mb.Name; – raterus

+0

¿Entonces dices que la sobrecarga de palabras clave es peligrosa? Entonces, ¿para qué sirve? – ahmet

Cuestiones relacionadas