为什么 c# 编译器从这段代码创建一个 PrivateImplementationDetails?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/729667/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 22:53:05  来源:igfitidea点击:

Why does the c# compiler create a PrivateImplementationDetails from this code?

c#

提问by Andrew Bullock

I've discovered that the following code:

我发现以下代码:

public static class MimeHelper
    {
        public static string GetMimeType(string strFileName)
        {
            string retval;
            switch (System.IO.Path.GetExtension(strFileName).ToLower())
            {
                case ".3dm": retval = "x-world/x-3dmf"; break;
                case ".3dmf": retval = "x-world/x-3dmf"; break;
                case ".a": retval = "application/octet-stream"; break;
                // etc...
                default: retval = "application/octet-stream"; break;
            }
            return retval;
        } 
    }

causes the compiler to create this namespaceless, internal class (copied from Reflector):

导致编译器创建这个无命名空间的内部类(从反射器复制):

<PrivateImplementationDetails>{621DEE27-4B15-4773-9203-D6658527CF2B}
    - $$method0x60000b0-1 : Dictionary<String, Int32>
    - Used By: MimeHelper.GetMimeType(String) : String

Why is that? How would I change the above code so it doesn't happen (just out of interest)

这是为什么?我将如何更改上面的代码以使其不会发生(只是出于兴趣)

Thanks

谢谢

Andrew

安德鲁

采纳答案by tvanfosson

It's creating the dictionary to handle the lookups of the various cases in the switch statement instead of making several branching ifs out of it to set the return value. Trust me -- you don't want to change how it's doing it -- unless you want to make the map explicit.

它正在创建字典来处理 switch 语句中各种情况的查找,而不是从中创建几个分支来设置返回值。相信我——你不想改变它的工作方式——除非你想让地图明确。

ASIDE: I had originally assumed that the dictionary stored a map from each case to the an index into another map for the return values. According to @Scott (see comments), it actually stores an index to a label for the code that should be executed for that case. This makes absolute sense when you consider that the code that would be executed for each case may differ and may be much longer than in the given example.

旁白:我最初假设字典存储了从每个案例到索引的映射到另一个映射的返回值。根据@Scott(见评论),它实际上存储了一个索引,指向应该在这种情况下执行的代码的标签。当您考虑到为每种情况执行的代码可能不同并且可能比给定示例中的代码长得多时,这绝对有意义。

EDIT: Based on your comment, I think I might be tempted to store the mappings in an external configuration file, read them in during start up, and construct the actual map -- either a single level map from key to value or a similar multilevel map from key to index and index to value. I think it would be easier to maintain these mappings in a configuration file than to update the code every time you needed to add or remove a particular case.

编辑:根据您的评论,我想我可能想将映射存储在外部配置文件中,在启动期间读取它们,并构建实际映射——从键到值的单级映射或类似的多级映射从键到索引和索引到值的映射。我认为在配置文件中维护这些映射比每次需要添加或删除特定案例时更新代码更容易。

回答by Anton Gogolev

See this, for example.

例如,请参阅

回答by Anton Gogolev

What is happening is compiler is creating an internal class that it emits at compile time. This class is called <PrivateImplementationDetails>{99999999-9999-9999-9999-999999999999}, the GUID component of this class is generated at compile time so it changes with every build. Internally in this class there is a dictionary that contains the different case variables, and an int corresponding to each value. It then replaces the switch statement with a lookup in the dictionary to get the corresponding int, and does a switch on the int value (much more efficient than doing a bunch of sting compares).

发生的事情是编译器正在创建它在编译时发出的内部类。此类称为<PrivateImplementationDetails>{99999999-9999-9999-9999-999999999999},此类的 GUID 组件是在编译时生成的,因此它会随着每次构建而更改。在这个类内部有一个包含不同 case 变量的字典,以及一个对应于每个值的 int。然后它用字典中的查找替换 switch 语句以获取相应的 int,并对 int 值进行 switch(比执行一堆 sting 比较效率更高)。