类型转换是代码设计不佳的标志吗?

时间:2010-12-16 20:45:39

标签: c# user-interface casting

我将是第一个告诉别人我的代码设计可以使用改进的人。我不禁感到,当我在我的代码中进行类型转换时,它表明某些东西需要重新设计以删除类型转换。这个问题有两部分,第一部分只是发布的一部分:类型转换是代码设计不佳的标志吗?

第二个问题是基于第一个问题,如果类型转换是我认为的那样邪恶,那么如何避免以下情况呢?

class InputPanel : Control
{
  public event EventHandler InputEvent;
}

class OutputPanel : Control
{
}

class MainWindow : Form
{
  public MainWindow()
  {
    var loadButton = new Button();
    loadButton.Click += new EventHandler(HandleButtonClick);

    var inputPanel = new InputPanel();
    inputPanel.InputEvent += new EventHandler(HandleInputEvent);
    bodyControl = inputPanel;
  }

  private void HandleButtonClick(object sender, EventArgs args)
  {
    OpenFileDialog dialog = new OpenFileDialog();
    if (dialog.ShowDialog(this) == DialogResult.OK)
    {
      var data = LoadDataFromFile(dialog.FileName);
      var inputPanel = bodyControl as InputPanel; // Ugly typecast...
      if (inputPanel != null)
      {
        inputPanel.PopulateFromData(data);
      }
    }
  }

  private void HandleInputEvent(object sender, EventArgs args) 
  {
    var outputPanel = new OutputPanel();
    bodyControl = outputPanel;
  }

  Control BodyControl;
}

上述代码背后的原因是MainWindow表单包含一个MenuStrip(在本例中简化为一个按钮)和一个控件(BodyControl)。由于显示的控件需要从输入面板更改为输出面板,通过单击按钮,您可以简单地重新分配BodyControl字段(调整父级等)。这意味着一次只加载一个面板,布局逻辑变得简化,因为在MainWindow中只有一个面板(如果包含MenuStrip,则为两个),而不是根据哪个状态有条件地布置多个“主体”控件。程序在(输入与输出)。

2 个答案:

答案 0 :(得分:6)

对于两个控件(inputPaneloutputPanel),您可以使用interfacecommon base class来使代码更清晰(并避免类型转换)。只需将BodyControl存储为基类或接口(而不是Control)。假设接口或基类实现了PopulateFromData方法,则根本不需要转换。

另外请确保您了解C#中的where clause。在处理类似场景时它可以派上用场。

答案 1 :(得分:3)

Typecasts不是代码设计不佳的标志。然而,大量的类型转换在某种程度上表明代码设计不佳。

  

然后如何避免以下情况?

您可以存储一个InputPanel和OutputPanel变量,并使用一个标志来指示您的类所处的“模式”(输入模式或输出模式)。

另外,我不明白:

var outputPanel = new OutputPanel();
bodyControl = outputPanel();

我认为应该以同样的方式阅读bodyControl = outputPanel; bodyControl = inputPanel;