2010-10-01 11 views
13
public class MyWebControl { 

    [ExternallyVisible] 
    public string StyleString {get;set;} 

} 

public class SmarterWebControl : MyWebControl { 

    [ExternallyVisible] 
    public string CssName{get;set;} 

    new public string StyleString {get;set;} //Doesn't work 

} 

¿Es posible eliminar el atributo en la subclase? Quiero que el atributo sea heredado por otras subclases, simplemente no esta.C# Anular un atributo en una subclase

Editar: ¡Vaya, parece que me olvidé de compilar o algo así porque el código como se publicó arriba, de hecho, funciona!

+0

contento de que funciona, yo estaba confundido en cuanto a por qué no lo haría. Sin embargo, tengo que decir que no estoy seguro de que me guste el uso de nuevos aquí (aunque soy un poco anti- nuevo en general). Para alguien que mira la clase no les dice por qué estás haciendo eso. Usar un atributo con un parámetro falso, por otro lado, es documentarse por sí mismo. –

+0

Es cierto, y si estuviera escribiendo todo desde el principio, probablemente lo haría de esa manera;) –

Respuesta

5

Funciona para mí.

Código de ensayo:

public static void Main() 
{ 
    var attribute = GetAttribute(typeof (MyWebControl), "StyleString", false); 
    Debug.Assert(attribute != null); 

    attribute = GetAttribute(typeof(SmarterWebControl), "StyleString", false); 
    Debug.Assert(attribute == null); 

    attribute = GetAttribute(typeof(SmarterWebControl), "StyleString", true); 
    Debug.Assert(attribute == null); 
} 

private static ExternallyVisibleAttribute GetAttribute(Type type, string propertyName, bool inherit) 
{ 
    PropertyInfo property = type.GetProperties().Where(p=>p.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); 

    var list = property.GetCustomAttributes(typeof(ExternallyVisibleAttribute), inherit).Select(o => (ExternallyVisibleAttribute)o); 

    return list.FirstOrDefault(); 
} 
13

Esto es exactamente por qué los atributos del marco que pueden ser "sobrescritos", toman un parámetro booleano que (a primera vista) parece inútil. Tome BrowsableAttribute por ejemplo; el parámetro booleano parecería ser juzgar obsoleta por el nombre, pero tomar este ejemplo:

class SomeComponent 
{ 
    [Browsable(true)] 
    public virtual string SomeInfo{get;set;} 
} 

class SomeOtherComponent : SomeComponent 
{ 
    [Browsable(false)] // this property should not be browsable any more 
    public override string SomeInfo{get;set;} 
} 

así, para responder a su pregunta, usted podría hacer su atributo ExternallyVisible tomar un parámetro booleano, para indicar si en realidad es externa visible, y cuando heredas puedes cambiar a falso, al igual que BrowsableAttribute.

2

Puede heredar el atributo y agregar una propiedad que controle si el código attrbiute se activa o no.

entonces puede anular el comportamiento de los atributos en la clase heredada?

por lo que usaría (si se ha añadido un parámetro al constructor)

[ExternallyVisible(false)] 

[ExternallyVisible(Enabled = false)] 

i fyou usado una propiedad de habilitado en la clase atrtibute

3

No entiendo cuál es el problema. Su código publicado hace lo esperado (al menos, lo que parece que espera que haga) en mi prueba: es decir, la propiedad StyleString no tiene el atributo ExternallyVisible. Aquí está mi código de prueba:

[AttributeUsage(AttributeTargets.Property)] 
public class ExternallyVisible : Attribute 
{ 
} 

public class MyWebControl 
{ 
    [ExternallyVisible] 
    public string StyleString { get; set; } 
} 

public class SmarterWebControl : MyWebControl 
{ 

    [ExternallyVisible] 
    public string CssName { get; set; } 

    new public string StyleString { get; set; } //Doesn't work 

} 

class Program 
{ 
    static void Main() 
    { 
     MyWebControl myctrl = new MyWebControl(); 
     SmarterWebControl smartctrl = new SmarterWebControl(); 

     MemberInfo info = typeof(SmarterWebControl); 
     PropertyInfo[] props = (typeof(SmarterWebControl)).GetProperties(); 
     Console.WriteLine("{0} properties", props.Length); 

     foreach (var prop in props) 
     { 
      Console.WriteLine(prop.Name); 
      foreach (var attr in prop.GetCustomAttributes(true)) 
      { 
       Console.WriteLine(" " + attr); 
      } 
     } 

     Console.ReadLine(); 
    } 

} 

En .NET 4.0, consigo esta salida:

2 properties 
CssName 
    sotesto.ExternallyVisible 
StyleString 

En otras palabras, el atributo no se aplica a la propiedad StyleString.

+0

Dale un golpe. :) –

Cuestiones relacionadas