Вызов виртуального члена в конструкторе

В моем приложении я использую одну и ту же winform в разных контекстах для управления видимостью кнопок, включения текстовых полей и текста заголовка winform. Я решил сделать это, просто передав строку в конструктор формы и проверив ее с помощью пары операторов if, которые, в свою очередь, содержат желаемые настройки winform.

if (formContext == "add")
{
    Text = "Add member";
}
if (formContext == "edit")
{
    Text = "Change role";
    userTextBox.Enabled = false;
    searchButton.Visible = false;
}

Это работает нормально, однако ключевые слова «Текст» получают синюю волнистую линию, добавленную ReSharper со следующим сообщением: Вызов виртуального члена в конструкторе. Это потенциальная проблема или просто какое-то излишне восторженное сообщение ReSharper.

Будем очень признательны за любые разъяснения или предложения по улучшению моей реализации.


person Sakkle    schedule 19.01.2009    source источник


Ответы (4)


Вызов виртуального члена в базовом классе ctor может вызвать выполнение некоторой логики в подклассе перед вызовом ctor подкласса (и, таким образом, до того, как объект получит возможность инициализировать себя до согласованного состояния).

Это просто приятное напоминание, чтобы вы знали, что делаете что-то, что потенциально может вызвать неприятное неожиданное поведение.

person mookid8000    schedule 19.01.2009
comment
Да ... об этом я и сам думал. Любые предложения относительно того, как я мог бы сделать это лучше. Стабильность - приоритет номер один в этом проекте, и я бы предпочел избегать возможного неожиданного поведения. - person Sakkle; 19.01.2009
comment
Вы имеете в виду предложения помимо того, что просто не вызываете виртуальные методы в вашем базовом классе ctor? :-) В этой ситуации вы можете использовать привязку данных для привязки свойства Text формы к строковому полю в классе модели GUI, которое затем будет содержать необходимую логику для определения того, что должна говорить строка заголовка. - person mookid8000; 19.01.2009
comment
Да ... Возможно, я мог бы, хотя я не знал, с чего начать, и, думаю, мне пришлось бы сделать то же самое для кнопки и текстового поля. - person Sakkle; 19.01.2009

В дополнение к существующим ответам для форм вы можете добавить обработчик события Load:

Load += delegate
{
    if (formContext == "add")
    {
        Text = "Add member";
    }
    if (formContext == "edit")
    {
        Text = "Change role";
        userTextBox.Enabled = false;
        searchkButton.Visible = false;
    }
};
person Jon Skeet    schedule 19.01.2009
comment
Это кажется самым простым и лучшим решением того, что я пытаюсь выполнить, без необходимости переписывать много кода. Да ... мне лень: P - person Sakkle; 19.01.2009

Просто запечатайте свой класс.

person Ilya Ryzhenkov    schedule 19.01.2009
comment
msdn.microsoft.com/en-us/library/88c54tsw (VS.71) .aspx Запечатанный класс не может быть унаследован, поэтому производный класс не может переопределить виртуальный член. - person ng5000; 19.01.2009

Я бы посоветовал вам переписать класс следующим образом:

public partial class Form1 : Form
{
    public enum FormContextMode
    {
        Add,
        Edit
    }

    private FormContextMode m_mode = FormContextMode.Add; 

    public Form1( FormContextMode mode )
    {
        InitializeComponent();
        m_mode = mode;
        Load += delegate { UpdateForm(); };
    }

    private void UpdateForm()
    {
        if( m_mode == FormContextMode.Add )
        {
            Text = "Add member";    
        }
        else if( m_mode == FormContextMode.Edit )
        {
            Text = "Change role";
            userTextBox.Enabled = false;
            searchkButton.Visible = false;
        }
    }
}
person ng5000    schedule 19.01.2009
comment
Вам не нужно подписываться на собственное событие Load, просто переопределите метод OnLoad. - person Ilya Ryzhenkov; 19.01.2009
comment
Да, я согласен с Ильей - лучше перегрузить метод, тогда вам не нужно будет помнить об отказе от подписки на событие + (и это интуитивное заявление), вероятно, быстрее. - person ng5000; 19.01.2009
comment
Не создавайте второго ответа, это просто сбивает с толку. Этот ответ сам по себе не отвечает требованиям каких-либо разъяснений или предложений по улучшению в вопросе. - person bzlm; 26.01.2009
comment
Исходный ответ удален и заменен этим, обновленным, как показано. - person ng5000; 27.01.2009