我有一个函数将控件作为参数,并根据控件的类型(例如: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..... }
我想知道这是否是最好的方法.
我知道其他一些方法可以做同样的事情(例如:使用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..... } } }
但我发现这最后的解决方案相当冗长而且不太实用.
我希望能够直接打开控件的类型,但是由于switch的case语句不能包含变量而无法使用字符串表示(我根本不喜欢),因此无法这样做.
那么什么才是真正做到性能的最好方法呢?在你看来,最好的办法是什么? (不一定是性能方面,但例如“代码可读性明智”)
编辑:关于“我为什么要使用一个常用函数而不是特定于类型的特定方法”的主题,正在进行中,这里有更多信息:
我从我正在处理的应用程序的其他部分(type = Control)获取一个控制变量,我根据其类型对此变量做“做某事”.
基本上,我可以选择两个选项:要么我使用一个常用函数并检查函数体内控件的类型,以便我在某个时刻执行代码的正确部分(我现在选择的选项,但这可以更改),或者在调用类型特定的方法之前检查控件的类型.
无论哪种方式,我必须在某个时刻打开控件的类型,这是我的问题的主题(无论我怎么做,如果我可以这样说).
解决方法
我会使用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); }
这种方法的好处是一些可维护性改进:1.您将知道您没有为相同的参数类型注册多个处理程序(字典将抛出异常)2.您将分别拥有所有处理程序注册,这将允许您轻松找出处理特定参数类型的方法.3.由于所有处理程序定位逻辑都没有重复,因此很容易修改它以便处理固有类型(例如我的代码不执行此操作,但代码确实如此)