Reputation: 4012
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
}
Is it possible to remove the attribute in the subclass? I do want the attribute to get inherited by other subclasses, just not this one.
Edit: Whoops, looks like I forgot to compile or something because the code as posted above does, in fact, work!
Upvotes: 27
Views: 47790
Reputation: 133950
I don't understand what the trouble is. Your posted code does the expected thing (at least, what it appears you expect it to do) in my test: that is, the StyleString
property does not have the ExternallyVisible
attribute. Here's my test code:
[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, I get this output:
2 properties
CssName
sotesto.ExternallyVisible
StyleString
In other words, the attribute is not applied to the StyleString
property.
Upvotes: 4
Reputation: 136074
This is exactly why framework attributes that can be "overriden", take a boolean parameter which (on the face of it) seems pointless. Take BrowsableAttribute
for example; the boolean parameter would seem to be obsolete judging by the name, but take this example:
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;}
}
so, to answer your question, you could make your ExternallyVisible attribute take a boolean parameter, to indicate whether it is actually externally visible, and when you inherit you can change to false - just like BrowsableAttribute
.
Upvotes: 28
Reputation: 1889
It works for me.
Test code:
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();
}
Upvotes: 8
Reputation: 4836
You could inherit off the attribute and add a property that controls whether the attrbiute code fires or not.
then you can override the attributes behaviour on the inherited class?
so you would use (if you added a parameter to the constructor)
[ExternallyVisible(false)]
[ExternallyVisible(Enabled = false)]
i fyou used a property of enabled in the atrtibute class
Upvotes: 3