C# 如果案例不相交,则打开类型
根据,类型上使用的C# 如果案例不相交,则打开类型,c#,performance,types,switch-statement,C#,Performance,Types,Switch Statement,根据,类型上使用的switch语句是顺序敏感的: case子句的顺序现在很重要:就像catch子句一样,case子句 case子句不一定是不相交的,第一个 比赛会被挑选出来 如果类型上使用的switch语句尊重顺序,我假设它只不过是引擎盖下的If-else-If链。这一页也暗示了这一点:首先它给出了一个关于类型的switch语句的示例,然后它说“如果没有模式匹配,此代码可能按如下方式编写”,并显示一个if-else-if链 但在我的场景中,这些类型在继承或接口实现方面是不相关的,因此这些情况肯定
switch
语句是顺序敏感的:
case子句的顺序现在很重要:就像catch子句一样,case子句
case子句不一定是不相交的,第一个
比赛会被挑选出来
如果类型上使用的switch
语句尊重顺序,我假设它只不过是引擎盖下的If-else-If
链。这一页也暗示了这一点:首先它给出了一个关于类型的switch
语句的示例,然后它说“如果没有模式匹配,此代码可能按如下方式编写”,并显示一个if-else-if
链
但在我的场景中,这些类型在继承或接口实现方面是不相关的,因此这些情况肯定是不相交的
switch
语句转换为查找表吗情景: 我正在将自动生成的对象结构(由xsd.exe从xsd xml模式创建)中的数据解析到我自己的数据结构中。由于xsd模式使用了大量的choice语句,因此我经常使用以下模式:
static IContent ParseContent(object c)
{
// Because of the choice statements in the xsd, the object c can be an instance
// of many different (auto-generated) classes which are not related to each other
// in terms of inheritance or interface implementation.
if (c is class1 c1) // class1 is an auto-generated class from the xsd schema
return ParseClass1(c1);
else if (c is class2 c2) // class2 is an auto-generated class from the xsd schema
return ParseClass2(c2);
....
else if (c is class20 c20) // class20 is an auto-generated class from the xsd schema
return ParseClass20(c20);
else
throw new ArgumentException(...);
}
static MyClass1 ParseClass1(class1 c1) { ... } // MyClass1 implements IContent
...
static MyClass20 ParseClass20(class20 c20) { ... } // MyClass20 implements IContent
我最近决定优化性能,这就是为什么我对开关的机制感兴趣
编译器会发现这一点并自动将switch语句转换为查找表吗
不可以,因为它不能保证在将代码编译成DLL后,类将保持不相交
如果没有,是否有办法强制编译器将其转换为查找表
如果您始终打开某个叶类型,则可以将其转换为打开该类型的全名:
switch (c?.GetType().FullName) {
case "MyNamespace.Class1": {
return ParseClass1((MyNamespace.Class1)c);
}
case "MyNamespace.Class2": {
return ParseClass2((MyNamespace.Class2)c);
}
...
}
您可以完全消除交换机,用动态调度替换它:
static IContent ParseContent(dynamic c) => ParseClass(c);
// ^^^^^^^
// This is the part where "magic" takes place
IContent ParseClass(class1 c) {...}
IContent ParseClass(class2 c) {...}
...
IContent ParseClass(class20 c) {...}
IContent ParseClass(object c) => throw new ArgumentException(...);
关于您的FullName
建议:有没有一种方法可以让它在使用模糊器的情况下工作nameof(class1)
不会给出全名…@Kjara您应该能够使用typeof(class1)。全名
。根据,nameof
在编译时应用(在混淆之前)。我假设typeof
也是,这意味着typeof(…)。FullName
在混淆之前给出名称。但是GetType().FullName
给出运行时类型名称,即在混淆之后。因此,这种方法似乎不起作用…@Kjaratypeof
在编译时应用,但FullName
不起作用。它将提供一个模糊的名称.Hm,但是运行时应用程序不会给性能带来损失吗?我想知道这有多重要。看来我需要试试。但是这种运行时依赖性有点不令人满意。