Céd*_*vin 60 .net c# optimization switch-statement
可能重复:
C# - "开启类型"有比这更好的选择吗?
你好假设我在类类型上得到一个很大的if/else.有没有办法用开关盒做到这一点?
示例:
function test(object obj)
{
if(obj is WebControl)
{
}else if(obj is TextBox)
{
}
else if(obj is ComboBox)
{
}
Run Code Online (Sandbox Code Playgroud)
等......
我想创造类似的东西
switch(obj)
{
case is TextBox:
break;
case is ComboBox:
break;
}
Run Code Online (Sandbox Code Playgroud)
}
Ste*_*eve 72
没有.
http://blogs.msdn.com/b/peterhal/archive/2005/07/05/435760.aspx
我们收到很多关于C#语言添加的请求,今天我将讨论一个比较常见的 - 开启类型.打开类型看起来像一个非常有用和直接的功能:添加一个类似开关的结构,它打开表达式的类型,而不是值.这可能看起来像这样:
switch typeof(e) {
case int: ... break;
case string: ... break;
case double: ... break;
default: ... break;
}
Run Code Online (Sandbox Code Playgroud)
这种语句对于在不相交的类型层次结构中添加虚拟方法(如调度)或在包含您不拥有的类型的类型层次结构上非常有用.看到这样的例子,您可以很容易地得出结论,该功能将是直截了当且有用的.它甚至可能让你想到"为什么那些#*&%$懒惰的C#语言设计师只是让我的生活更轻松,并添加这种简单,省时的语言功能?"
不幸的是,像许多"简单"的语言功能一样,类型切换并不像它第一次出现那么简单.当你看到一个更重要的,同样重要的例子时,麻烦就开始了:
class C {}
interface I {}
class D : C, I {}
switch typeof(e) {
case C: … break;
case I: … break;
default: … break;
}
Run Code Online (Sandbox Code Playgroud)
链接:https://blogs.msdn.microsoft.com/peterhal/2005/07/05/many-questions-switch-on-type/
cdi*_*ins 54
以下代码或多或少地起作用,因为人们期望只查看实际类型的类型开关(例如,返回的内容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");
}
Run Code Online (Sandbox Code Playgroud)
这是使其工作所需的机器.
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); }
}
Run Code Online (Sandbox Code Playgroud)
Tim*_*uri 24
是的,你可以打开名字......
switch (obj.GetType().Name)
{
case "TextBox":...
}
Run Code Online (Sandbox Code Playgroud)
Eni*_*ity 13
这是一个保持真实的选项我可以满足OP要求能够打开类型.如果你足够眯眼,它几乎看起来像一个真正的开关声明.
调用代码如下所示:
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);
Run Code Online (Sandbox Code Playgroud)
在x
上述每个拉姆达是强类型.不需要铸造.
为了实现这项神奇的工作,您需要以下两种方法:
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;
}
Run Code Online (Sandbox Code Playgroud)
几乎给你的眼睛带来了眼泪,对吧?
尽管如此,它仍然有效.请享用.
最简单的事情可能是使用动力学,即你定义简单的方法,如Yuval Peled答案:
void Test(WebControl c)
{
...
}
void Test(ComboBox c)
{
...
}
Run Code Online (Sandbox Code Playgroud)
然后你不能直接调用Test(obj),因为重载解析是在编译时完成的.您必须将对象分配给动态,然后调用Test方法:
dynamic dynObj = obj;
Test(dynObj);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
94767 次 |
最近记录: |