Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果案例不相交,则打开类型_C#_Performance_Types_Switch Statement - Fatal编程技术网

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
    给出运行时类型名称,即在混淆之后。因此,这种方法似乎不起作用…@Kjara
    typeof
    在编译时应用,但
    FullName
    不起作用。它将提供一个模糊的名称.Hm,但是运行时应用程序不会给性能带来损失吗?我想知道这有多重要。看来我需要试试。但是这种运行时依赖性有点不令人满意。