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

} 

Est-il possible de supprimer l'attribut dans la sous-classe? Je veux que l'attribut soit hérité par d'autres sous-classes, mais pas par celui-ci.C# Remplacer un attribut dans une sous-classe

Editer: Oups, on dirait que j'ai oublié de compiler ou quelque chose parce que le code affiché ci-dessus fonctionne, en fait!

+0

heureux qui fonctionne, je suis perplexe quant à la raison pour laquelle il ne serait pas. Je dois dire cependant, je ne suis pas sûr que j'aime l'utilisation de nouveaux ici (bien que je suis un peu anti-nouveau en général). Pour quelqu'un qui regarde la classe, il ne leur dit pas pourquoi vous faites cela. L'utilisation d'un attribut avec un faux paramètre est en revanche auto-documenté. Imho –

+0

Vrai, et si j'écrivais le tout à partir de zéro, je le ferais probablement de cette façon;) –

Répondre

5

Cela fonctionne pour moi.

Code d'essai:

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

C'est exactement pourquoi les attributs de framework qui peuvent être "overriden", prennent un paramètre booléen qui (à première vue) semble inutile. Prenez BrowsableAttribute par exemple; le paramètre booléen semble être obsolète à en juger par le nom, mais prenez cet exemple:

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

donc, pour répondre à votre question, vous pouvez faire votre attribut ExternallyVisible prendre un paramètre booléen pour indiquer si elle est en réalité à l'extérieur visible, et quand vous héritez, vous pouvez changer à false - tout comme BrowsableAttribute.

2

Vous pouvez hériter de l'attribut et ajouter une propriété qui contrôle si le code attrbiute se déclenche ou non.

alors vous pouvez remplacer le comportement des attributs sur la classe héritée?

de sorte que vous utilisez (si vous avez ajouté un paramètre au constructeur)

[ExternallyVisible(false)] 

[ExternallyVisible(Enabled = false)] 

i fyou utilisé une propriété de permis dans la classe atrtibute

3

Je ne comprends pas ce que le problème est. Votre code posté fait la chose attendue (du moins ce que vous attendez de lui) dans mon test: la propriété StyleString n'a pas l'attribut ExternallyVisible. Voici mon code de test:

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

} 

Dans .NET 4.0, je reçois cette sortie:

2 properties 
CssName 
    sotesto.ExternallyVisible 
StyleString 

En d'autres termes, l'attribut est pas appliqué à la propriété StyleString.

+0

Battez-moi. :) –

Questions connexes