С# Переопределить атрибут в подклассе
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
}
Можно ли удалить атрибут в подклассе? Я хочу, чтобы атрибут получал унаследованный другими подклассами, а не этот.
Изменить: Упс, похоже, я забыл скомпилировать или что-то, потому что код, как выложено выше, действительно работает!
Ответы
Ответ 1
Это работает для меня.
Тестовый код:
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();
}
Ответ 2
Именно поэтому атрибуты фреймворка, которые можно "переопределить", принимают логический параметр, который (на первый взгляд) кажется бессмысленным. Возьмите BrowsableAttribute
для примера; Судя по названию, логический параметр устарел, но возьмем следующий пример:
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;}
}
поэтому, чтобы ответить на ваш вопрос, вы могли бы сделать так, чтобы ваш атрибут ExternallyVisible принял логический параметр, чтобы указать, является ли он на самом деле видимым извне, и когда вы наследуете, вы можете изменить на false - точно так же, как BrowsableAttribute
.
Ответ 3
Я не понимаю, в чем проблема. Размещенный код выполняет ожидаемое действие (по крайней мере то, что, по-видимому, вы ожидаете) в моем тесте: то есть свойство StyleString
не имеет атрибута ExternallyVisible
. Вот мой тестовый код:
[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();
}
}
В.NET 4.0 я получаю этот вывод:
2 properties
CssName
sotesto.ExternallyVisible
StyleString
Другими словами, атрибут не применяется к свойству StyleString
.
Ответ 4
Вы можете наследовать атрибут и добавить свойство, которое контролирует, запускается ли код attrbiute или нет.
то вы можете переопределить поведение атрибутов в унаследованном классе?
чтобы вы использовали (если вы добавили параметр в конструктор)
[ExternallyVisible(false)]
[ExternallyVisible(Enabled = false)]
i fyou используется свойство enabled в классе atrtibute