在C#/ WPF中确定控件类型的最有效方法

Dav*_*vid 6 c# syntax wpf types

我有一个函数,它将控件作为参数,并根据控件的类型(例如:TextBox,ComboBox,RadioButton等...),它执行特定于类型的代码:

internal static void DoSomething(Control control)
{
    if (control is Button)
    {
        // code for button
    }

    else if (control is CheckBox)
    {
        // code for CheckBox
    }

    else if (control is TextBox)
    {
        // code for TextBox
    }

    // etc.....
}
Run Code Online (Sandbox Code Playgroud)

我想知道这是否是最好的方法.

我知道其他一些方法可以做同样的事情(例如:使用GetType()此类型的字符串表示来查找控件的类型),Microsoft的代码分析工具告诉我使用'as'代替'is'就像这样(因为它在性能方面更好):

internal static void DoSomething(Control control)
{
    Button button = control as Button
    if (button != null)
    {
        // code for button
    }

    else
    {
        CheckBox checkBox = control as CheckBox;
        if (checkBox != null)
        {
            // code for CheckBox
        }

        else
        {
            TextBox textBox = control as TextBox;
            if (textBox != null)
            {
                // code for TextBox
            }

            // etc.....
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但我发现这最后的解决方案相当冗长而且不太实用.我希望能够直接打开控件的类型,但是由于switch的case语句不能包含变量而无法使用字符串表示(我根本不喜欢),因此无法这样做.

那么什么才是真正做到性能的最好方法呢?在你看来,最好的办法是什么?(不一定是性能方面,但例如"代码可读性明智")

编辑:关于"我为什么要使用一个常用函数而不是特定于类型的特定方法"的主题,正在进行中,这里有更多信息:

我从我正在处理的应用程序的其他部分(type = Control)获取一个控制变量,我根据其类型对此变量做"做某事".

基本上,我可以选择两个选项:要么我使用一个常用函数并检查函数体内控件的类型,以便我在某个时刻执行代码的正确部分(我现在选择的选项,但这可以更改),或者在调用类型特定的方法之前检查控件的类型.

无论哪种方式,我必须在某个时刻打开控件的类型,是我的问题的主题(无论我怎么做,如果我可以这样说).

Sno*_*ear 8

我会用Dictionary它和(每个处理程序的单独方法):

private static readonly Dictionary<Type, Action<Control>> _handlers
           = new Dictionary<Type, Action<Control>>();


// Handle.. methods
private static void HandleButton(Button button) { ... }
private static void HandleListbox(Listbox listbox) { ... }

private static void RegisterHandler<T>(Action<T> handler)
      where T: Control
{
    _handlers.Add(typeof(T), o => handler((T)o));
}

// invoke this method in static constructor
private static void InitializeHandlers()
{
    RegisterHandler<Button>(HandleButton);
    RegisterHandler<Listbox>(HandleListbox);
}

// finally usage:
internal static void DoSomething(Control control)
{
    var handler = _handlers[control.GetType()];
    handler(control);
}
Run Code Online (Sandbox Code Playgroud)

这种方法的好处是一些可维护性改进:
1.您将知道您没有为相同的参数类型注册多个处理程序(字典将抛出异常)
2.您将分别拥有所有处理程序注册,这将允许您轻松查找out哪个方法处理特定的参数类型.
3.由于所有处理程序定位逻辑都没有重复,因此很容易修改它以便处理固有类型(例如我的代码不执行此操作,但代码确实如此)

  • +1:我不喜欢在类型上做一个switch/if-else,感觉不对.这更清洁. (2认同)
  • +1:通用RegisterHandler特别整洁. (2认同)