C# сокрытие метода на производном классе и использование атрибутов
У меня есть образец объектной модели, как показано ниже.
[AttributeUsage(AttributeTargets.Method)]
public sealed class CandidateApiForMenuItem : Attribute
{
public CandidateApiForMenuItem(string caption)
{
this.Caption = caption;
}
public string Caption { get; set; }
}
public class FormDataElementBase
{
public FormDataElementBase()
{
}
[CandidateApiForMenuItem("Add PanelGroup")]
public void AddPanelGroup()
{
///...
}
[CandidateApiForMenuItem("Add BoxGroup")]
public void AddBoxGroup()
{
///...
}
[CandidateApiForMenuItem("Remove")]
public void Remove()
{
///...
}
public void GenerateGroupPopupMenuItems()
{
foreach (MethodInfo methodInfo in this.GetType().GetMethods())
{
if (methodInfo.GetCustomAttribute(typeof(CandidateApiForMenuItem)) != null)
{
// This is true both for FormDataElementBase and all derived
// but I want to hide Remove method inside MainGroup class
// However it is displayed again
};
};
}
}
public class BoxGroup : FormDataElementBase
{
}
public class PanelGroup : FormDataElementBase
{
}
public class MainGroup : FormDataElementBase
{
private void Remove()
{
}
}
Когда пользователь щелкнет правой кнопкой мыши, приложение отобразит PopupMenu (метод GenerateGroupPopupMenuItems). Элементы меню будут основаны на методах, для которых объявлен CandidateApiForMenuItem. Однако есть производный класс (MainGroup), в котором некоторые методы (например, Remove) не должны отображаться. То, что я сделал, внутри MainGroup объявил метод Remove закрытым. Тем не менее, он отображается снова.
Не могли бы вы дать мне знать, что я делаю здесь?
Благодарю.
1 ответ
Прежде всего, this.GetType().GetMethods()
без параметров возвращает только общедоступные экземпляры (т.е. не статические) методы. Так MainGroup.Remove
не будет возвращен этим звонком.
Если вы делаете MainGroup.Remove
общественности, this.GetType().GetMethods()
вернет оба метода - для базового класса и для производного. Полагаю, не то, что вы хотите.
Если вы делаете FormDataElementBase.Remove
виртуальный и MainGroup.Remove
переопределить, GetMethods вернет только один Remove
метод (с DeclaringType==typeof(MainGroup)
) - это лучше.
И, наконец, я бы предложил ввести еще один атрибут, скажем, CandidateApiIgnore
, Если мы пометим переопределенный метод с этим атрибутом и изменим следующим образом GenerateGroupPopupMenuItems
Метод, материал должен работать:
[AttributeUsage(AttributeTargets.Method)]
public sealed class CandidateApiIgnore : Attribute
{
public CandidateApiIgnore() { }
}
public class FormDataElementBase
{
///...
[CandidateApiForMenuItem("Remove")]
public virtual void Remove()
{
///...
}
public void GenerateGroupPopupMenuItems()
{
foreach (MethodInfo methodInfo in this.GetType().GetMethods())
{
if (methodInfo.GetCustomAttribute(typeof(CandidateApiForMenuItem)) != null &&
methodInfo.GetCustomAttribute(typeof(CandidateApiIgnore)) == null)
{
// If a method is overridden and marked with
// CandidateApiIgnore attribute in a derived
// class, it won't be processed here.
};
};
}
public class MainGroup : FormDataElementBase
{
[CandidateApiIgnore]
public override void Remove()
{
throw new NotSupportedException();
}
}