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();
    }
}
Другие вопросы по тегам