2010-10-01 18 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 

} 

È possibile rimuovere l'attributo nella sottoclasse? Voglio che l'attributo venga ereditato da altre sottoclassi, ma non da questo.C# Sostituisce un attributo in una sottoclasse

Modifica: Whoops, sembra che ho dimenticato di compilare o qualcosa perché il codice come pubblicato sopra, infatti, funziona!

+0

contento che funziona, ero perplesso sul motivo per cui non sarebbe. Devo dire però, non sono sicuro che mi piaccia l'uso del nuovo qui (anche se sono un po 'anti-nuovo in generale). Per qualcuno che guarda la classe non dice loro perché lo stai facendo. D'altra parte l'utilizzo di un attributo con un parametro falso è auto-documentato imho –

+0

Vero, e se scrivessi tutto da zero probabilmente lo farei in quel modo;) –

risposta

5

Funziona per me.

Codice di prova:

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

Questo è esattamente il motivo per cui gli attributi di framework che possono essere "sovrascritti", prendono un parametro booleano che (a prima vista) sembra inutile. Prendi ad esempio BrowsableAttribute; il parametro booleano sembrerebbe essere a giudicare obsoleta dal nome, ma prendere questo esempio:

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;} 
} 

così, per rispondere alla tua domanda, si potrebbe rendere il vostro attributo ExternallyVisible prendere un parametro booleano, per indicare se in realtà è esternamente visibile e quando si eredita, è possibile passare a false, proprio come BrowsableAttribute.

2

È possibile ereditare l'attributo e aggiungere una proprietà che controlla se il codice attrbiute si attiva o meno.

quindi è possibile sovrascrivere il comportamento degli attributi nella classe ereditata?

così si usa (se è stato aggiunto un parametro al costruttore)

[ExternallyVisible(false)] 

[ExternallyVisible(Enabled = false)] 

i fyou usato una proprietà abilitata nella classe atrtibute

3

Non capisco che cosa il problema è. Il tuo codice postato fa la cosa che ti aspetti (almeno, quello che ti aspetti che faccia) nel mio test: cioè, la proprietà StyleString non ha l'attributo ExternallyVisible. Ecco il mio codice di prova:

[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(); 
    } 

} 

In .NET 4.0, ottengo questo output:

2 properties 
CssName 
    sotesto.ExternallyVisible 
StyleString 

In altre parole, l'attributo non viene applicato alla proprietà StyleString.

+0

Mi picchia. :) –

Problemi correlati