关于C#:构造函数中的虚拟成员调用

Virtual member call in constructor

本问题已经有最佳答案,请猛点这里访问。

在我的应用程序中,我在不同的上下文中运行同一个WinForm,以控制按钮的可见性、文本字段和WinForm标题文本的启用。我决定这样做的方法就是简单地将一个字符串传递给表单构造函数,然后用几个if语句检查它,这些语句反过来包含所需的winform调整。

1
2
3
4
5
6
7
8
9
10
if (formContext =="add")
{
    Text ="Add member";
}
if (formContext =="edit")
{
    Text ="Change role";
    userTextBox.Enabled = false;
    searchButton.Visible = false;
}

这很好,但是"文本"关键字会得到一条由resharper添加的蓝色斜线,并带有以下消息:viritual成员调用构造函数。这是一个潜在的问题,还是仅仅是某种过于热情的重新分析信息。

如对我的执行情况有任何澄清或建议,将不胜感激。


基类ctor中的虚拟成员调用可能会导致在调用子类的ctor之前(因此在对象有机会将自身初始化为一致状态之前),在子类中运行某些逻辑。

这只是一个很好的提醒,所以你知道你正在做的事情可能会导致一些令人讨厌的意外行为。


除了现有答案之外,对于表单,您还可以添加加载事件处理程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
Load += delegate
{
    if (formContext =="add")
    {
        Text ="Add member";
    }
    if (formContext =="edit")
    {
        Text ="Change role";
        userTextBox.Enabled = false;
        searchkButton.Visible = false;
    }
};


把你的课封上。


我建议将您的类重写如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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;
        }
    }
}