18 c#
可能重复:
"开启类型"有比这更好的选择吗?
我需要迭代我的类的所有属性,并检查我的类型int是否需要做什么,如果它的字符串..然后做一些事情.我需要使用开关盒.这里我以下面的方式使用switch,但它要求一些常量.看下面的代码:
public static bool ValidateProperties(object o)
{
if(o !=null)
{
var sourceType = o.GetType();
var properties = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Static);
foreach (var property in properties)
{
var type = property.GetType();
switch (type)
{
*case typeof(int):* getting error here
// d
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
另外我想知道,我应该使用什么检查,typeof(int)或typeof(Int32)?
Mår*_*röm 45
您不能使用开关块来测试类型的值Type
.编译代码应该会给出一个错误,例如:
switch表达式或case标签必须是bool,char,string,integral,enum或相应的可空类型
你需要使用if
- else
语句.
另外:typeof(int)
和typeof(Int32)
等同的.int
是一个关键字,Int32
是类型名称.
UPDATE
如果您希望大多数类型都是内在类型,则可以通过使用开关块来提高性能Type.GetTypeCode(...)
.
例如:
switch (Type.GetTypeCode(type))
{
case TypeCode.Int32:
// It's an int
break;
case TypeCode.String:
// It's a string
break;
// Other type code cases here...
default:
// Fallback to using if-else statements...
if (type == typeof(MyCoolType))
{
// ...
}
else if (type == typeof(MyOtherType))
{
// ...
} // etc...
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*Jon 11
一个好的,可扩展的方法是根据你想要对那个类型的值做什么,制作一个适当类型的类型和委托的字典.
例如:
var typeProcessorMap = new Dictionary<Type, Delegate>
{
{ typeof(int), new Action<int>(i => { /* do something with i */ }) },
{ typeof(string), new Action<string>(s => { /* do something with s */ }) },
};
Run Code Online (Sandbox Code Playgroud)
然后:
void ValidateProperties(object o)
{
var t = o.GetType();
typeProcessorMap[t].DynamicInvoke(o); // invoke appropriate delegate
}
Run Code Online (Sandbox Code Playgroud)
此解决方案是可扩展的,即使在运行时也是可配置的,只要您保持typeProcessorMap
正确匹配的密钥和委托值类型也是类型安全的.
通常,最简单的解决方案是打开类型名称:
switch (type.Name)
{
case "Int32":
...
}
Run Code Online (Sandbox Code Playgroud)
这个“答案”是对乔恩答案的详尽阐述。(标记CW)
记录下来,DynamicInvoke
有点慢。为了说明这一点,请考虑以下程序:
void Main()
{
Func<int, string> myFunc = i => i.ToString();
myFunc.DynamicInvoke(1); // Invoke once so initial run costs are not considered
myFunc(1);
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 1000000; i++)
myFunc.DynamicInvoke(1);
stopwatch.Stop();
var elapsed = stopwatch.Elapsed;
stopwatch.Restart();
for (int i = 0; i < 1000000; i++)
myFunc(1);
stopwatch.Stop();
var elapsed2 = stopwatch.Elapsed;
Console.WriteLine("DynamicInvoke: " + elapsed);
Console.WriteLine("Direct Invocation: " + elapsed2);
}
Run Code Online (Sandbox Code Playgroud)
打印输出:
DynamicInvoke:00:00:03.1959900
直接调用:00:00:00.0735220
这意味着DynamicInvoke
(在这种简单情况下)比直接调用慢42倍。
归档时间: |
|
查看次数: |
63179 次 |
最近记录: |