C# 切换 PropertyType
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/91563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Switch over PropertyType
提问by Boris Callens
How can I make this work?
我怎样才能使这项工作?
switch(property.PropertyType){
case typeof(Boolean):
//doStuff
break;
case typeof(String):
//doOtherStuff
break;
default: break;
}
I don't want to use the name since string comparing for types is just awfull and can be subject to change.
我不想使用该名称,因为类型的字符串比较非常糟糕并且可能会发生变化。
采纳答案by Jorge Ferreira
System.Type propertyType = typeof(Boolean);
System.TypeCode typeCode = Type.GetTypeCode(propertyType);
switch (typeCode)
{
case TypeCode.Boolean:
//doStuff
break;
case TypeCode.String:
//doOtherStuff
break;
default: break;
}
You can use an hybrid approach for TypeCode.Object where you dynamic if with typeof. This is very fast because for the first part - the switch - the compiler can decide based on a lookup table.
您可以对 TypeCode.Object 使用混合方法,如果使用 typeof 则动态。这非常快,因为对于第一部分 - 开关 - 编译器可以根据查找表做出决定。
回答by Phil Wright
Do not worry about using strings within a switch because if you have several the compiler will automatically convert it into a hash lookup giving decent performance despite it looking pretty aweful.
不要担心在 switch 中使用字符串,因为如果你有几个,编译器会自动将它转换为散列查找,尽管它看起来非常棒,但性能不错。
The problem of type strings changing can be solved by making it into an explicit hash lookup yourself and populating the constents of the hash in a static constructor. That way the hash is populate with the correct strings at runtime so they remain correct.
类型字符串改变的问题可以通过自己将它变成一个显式的散列查找并在静态构造函数中填充散列的内容来解决。这样散列在运行时填充正确的字符串,因此它们保持正确。
回答by Sam Meldrum
You can't do this with switch in c# as the case has to be constant.
你不能用 c# 中的 switch 来做到这一点,因为情况必须是恒定的。
What is wrong with:
出什么问题了:
if(property.PropertyType == typeof(bool)) {
//dostuff;
}
else if (property.PropertyType == typeof(string)) {
//do other stuff;
}
回答by user17527
Just use the normal if/else if/else pattern:
只需使用正常的 if/else if/else 模式:
if (property.PropertyType == typeof(Boolean))
{
}
else if (property.PropertyType == typeof(String))
{
}
else if (...)
{
}
回答by Paul van Brenk
You can't. What you can do is create a mapping between Types and a delegate using a dictionary:
你不能。您可以做的是使用字典在类型和委托之间创建映射:
var TypeMapping = new Dictionary<Type, Action<string>>(){
{typeof(string), (x)=>Console.WriteLine("string")},
{typeof(bool), (x)=>Console.WriteLine("bool")}
};
string s = "my string";
TypeMapping[s.GetType()]("foo");
TypeMapping[true.GetType()]("true");
回答by xan
I recently had to do something similar and using switch wasn't an option. Doing an == on the typeof(x) is fine, but a more elegant way might be to do something like this:
我最近不得不做类似的事情,并且不能使用 switch。在 typeof(x) 上做 == 很好,但更优雅的方法可能是做这样的事情:
if(property.PropertyType is bool){
//dostuff;
}
else if (property.PropertyType is string){
//do other stuff;
}
But, I'm not certain that you can use the "is" keyword in this way, I think it only works for objects...
但是,我不确定您是否可以以这种方式使用“is”关键字,我认为它仅适用于对象...
回答by Josh
I think what you are looking for here is a good Map. Using delegates and a Generic IDictionary you can do what you want.
我认为您在这里寻找的是一张好的地图。使用委托和通用 IDictionary 你可以做你想做的事。
Try something like this:
尝试这样的事情:
private delegate object MyDelegate();
private IDictionary<Type, MyDelegate> functionMap = new IDictionary<Type, MyDelegate>();
public Init()
{
functionMap.Add(typeof(String), someFunction);
functionMap.Add(tyepof(Boolean), someOtherFunction);
}
public T doStuff<T>(Type someType)
{
return (T)functionMap[someType]();
}
回答by timvw
I personally prefer the Dictionary<Type, other>
approach the most... I can even provide you another example: http://www.timvw.be/presenting-namevaluecollectionhelper/
我个人Dictionary<Type, other>
最喜欢这种方法......我什至可以为你提供另一个例子:http: //www.timvw.be/presenting-namevaluecollectionhelper/
In case you insist on writing a switch-case statement you could use the Type name...
如果您坚持编写 switch-case 语句,您可以使用类型名称...
switch (blah.PropertyType.FullName)
{
case typeof(int).FullName: break;
case typeof(string).FullName: break;
}
回答by Boris Callens
About the stringmatching: it was one of the reqs in the question to not do it through stringmatching.
关于字符串匹配:不通过字符串匹配是问题中的要求之一。
The dictionary is an approach I will use when I put this entire serialization algorithm in its own library. As for now I will first try the typeCode as my case only uses basic types. If that doesn't work I will go back to the swarm of if/elses :S
当我将整个序列化算法放在自己的库中时,我将使用字典方法。至于现在我将首先尝试 typeCode 因为我的情况只使用基本类型。如果那不起作用,我将回到 if/elses 群中:S
Before ppl ask me why I want my own serialization: 1) .net xml serialization doesn't serialize properties without setters 2) serialization has to comply to some legacy rules
在 ppl 之前问我为什么我想要我自己的序列化:1) .net xml 序列化不会在没有 setter 的情况下序列化属性 2) 序列化必须遵守一些遗留规则
回答by Krzysztof Branicki
C# 7.0 will support switch on types as a part of bigger pattern matching feature. This example is taken from .NET blog postthat announces new features:
C# 7.0 将支持打开类型作为更大模式匹配功能的一部分。此示例取自宣布新功能的.NET 博客文章:
switch(shape)
{
case Circle c:
WriteLine($"circle with radius {c.Radius}");
break;
case Rectangle s when (s.Length == s.Height):
WriteLine($"{s.Length} x {s.Height} square");
break;
case Rectangle r:
WriteLine($"{r.Length} x {r.Height} rectangle");
break;
default:
WriteLine("<unknown shape>");
break;
case null:
throw new ArgumentNullException(nameof(shape));
}