切换大小写typesC#

可能重复:
C# – 有没有比这更好的替代“打开types”?

你好,假设我得到一个大的if / else类types。 有一种方法可以用开关盒来做到这一点?

例如:

function test(object obj) { if(obj is WebControl) { }else if(obj is TextBox) { } else if(obj is ComboBox) { } 

等等

我想创build类似的东西

 switch(obj) { case is TextBox: break; case is ComboBox: break; } 

}

没有。

http://blogs.msdn.com/b/peterhal/archive/2005/07/05/435760.aspx

我们收到很多关于C#语言的附加条件的请求,今天我将要讨论一个比较常见的types – 打开types。 打开types看起来像是一个非常有用和简单的function:添加一个类似于开关的构造,用于切换expression式的types,而不是值。 这可能看起来像这样:

 switch typeof(e) { case int: ... break; case string: ... break; case double: ... break; default: ... break; } 

这种语句对于添加虚拟方法(如分派到不相交的types层次结构)或包含不属于您的types的types层次结构是非常有用的。 看到一个这样的例子,你可以很容易地得出结论,该function将是直接和有用的。 它甚至可能让你思考:“为什么这些#和$ C#语言devise人员为什么不让我的生活更轻松,并添加这个简单,省时的语言function?”

不幸的是,像许多“简单”的语言function,types切换并不像第一次出现那么简单。 当你看到一个更重要的同样重要的例子时,麻烦就开始了:

 class C {} interface I {} class D : C, I {} switch typeof(e) { case C: … break; case I: … break; default: … break; } 

链接: https : //blogs.msdn.microsoft.com/peterhal/2005/07/05/many-questions-switch-on-type/

下面的代码可以或多或less地工作,因为人们会期望一个只能看到实际types的types切换(例如GetType()返回的内容)。

 public static void TestTypeSwitch() { var ts = new TypeSwitch() .Case((int x) => Console.WriteLine("int")) .Case((bool x) => Console.WriteLine("bool")) .Case((string x) => Console.WriteLine("string")); ts.Switch(42); ts.Switch(false); ts.Switch("hello"); } 

这是使其工作所需的机器。

 public class TypeSwitch { Dictionary<Type, Action<object>> matches = new Dictionary<Type, Action<object>>(); public TypeSwitch Case<T>(Action<T> action) { matches.Add(typeof(T), (x) => action((T)x)); return this; } public void Switch(object x) { matches[x.GetType()](x); } } 

是的,你可以打开名字…

 switch (obj.GetType().Name) { case "TextBox":... } 

这是一个保持真实的选项,我可以使OP的要求能够打开types。 如果你狠狠的眯起来,它几乎看起来像一个真正的开关语句。

调用代码如下所示:

 var @switch = this.Switch(new [] { this.Case<WebControl>(x => { /* WebControl code here */ }), this.Case<TextBox>(x => { /* TextBox code here */ }), this.Case<ComboBox>(x => { /* ComboBox code here */ }), }); @switch(obj); 

上面每个lambda中的x是强types的。 不需要铸造。

为了使这个神奇的工作,你需要这两个方法:

 private Action<object> Switch(params Func<object, Action>[] tests) { return o => { var @case = tests .Select(f => f(o)) .FirstOrDefault(a => a != null); if (@case != null) { @case(); } }; } private Func<object, Action> Case<T>(Action<T> action) { return o => o is T ? (Action)(() => action((T)o)) : (Action)null; } 

几乎给你的眼睛带来了泪水,对吧?

尽pipe如此,它的工作。 请享用。

要做的最简单的事情可能是使用dynamic,即你定义的简单方法,如在Yuval Peled答案:

 void Test(WebControl c) { ... } void Test(ComboBox c) { ... } 

那么你不能直接调用Test(obj),因为重载parsing是在编译时完成的。 您必须将您的对象分配给dynamic,然后调用Test方法:

 dynamic dynObj = obj; Test(dynObj);