【问题标题】:Virtual member call in constructor [duplicate]构造函数中的虚拟成员调用[重复]
【发布时间】:2010-10-02 05:32:46
【问题描述】:

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

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

这很好用,但是“文本”关键字会得到 ReSharper 添加的蓝色波浪线,并带有以下消息:构造函数中的虚拟成员调用。 这是一个潜在的问题,还是只是某种过于热情的 ReSharper 信息。

任何关于改进我的实施的澄清或建议将不胜感激。

【问题讨论】:

    标签: c# visual-studio-2008 resharper


    【解决方案1】:

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

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

    【讨论】:

    • 是的……这与我自己的想法一致。关于如何更好地做到这一点的任何建议。稳定性是该项目的第一要务,我希望避免可能出现的意外行为。
    • 您的意思是除了不调用基类ctor中的虚拟方法之外的建议? :-) 在这种情况下,您可以使用数据绑定将表单的 Text 属性绑定到 GUI 模型类中的字符串字段,然后该字段将包含必要的逻辑来决定标题栏应该说什么。
    • 是的......我可能可以,虽然我不知道从哪里开始,我想我必须对按钮和文本字段做同样的事情。
    【解决方案2】:

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

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

    【讨论】:

    • 这似乎是我想要完成的最简单和最好的解决方案,无需我重写大量代码。是的......我很懒:P
    【解决方案3】:

    封住你的班级。

    【讨论】:

    【解决方案4】:

    我建议你重写你的课程如下:

    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;
            }
        }
    }
    

    【讨论】:

    • 不需要订阅自己的Load事件,重写OnLoad方法即可。
    • 是的,我同意 Ilya 的观点 - 最好重载该方法,这样您就不需要记住取消订阅事件 +(这是一个直觉声明)可能更快。
    • 不要创建“第二个答案”,这只会令人困惑。此答案本身不符合问题中“任何澄清或改进建议”的要求。
    • 原答案已删除,换成这个答案,如图所示。
    猜你喜欢
    • 2010-09-12
    • 1970-01-01
    • 2015-06-27
    • 2016-04-09
    • 2015-12-30
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 2019-05-06
    相关资源
    最近更新 更多