C#编译器和局部变量的缓存

xyz*_*xyz 2 c# compiler-construction optimization

编辑:糟糕 - 正如所指出的那样,没有办法知道所讨论的类的构造函数是否对它被调用的次数或次数敏感,或者对象的状态是否在方法中被更改,所以它必须每次都从头开始创建.忽略字典,只考虑在方法过程中在线创建的代理:-)


假设我使用Dictionary of Type to Action局部变量具有以下方法.

void TakeAction(Type type)
{
    // Random types chosen for example.
    var actions = new Dictionary<Type, Action>()
    {
        {typeof(StringBuilder), () =>
            {
                // ..
            }},
         {typeof(DateTime), () =>
            {
                // ..
            }}
    };

    actions[type].Invoke();
}
Run Code Online (Sandbox Code Playgroud)

调用方法时,Dictionary总是相同的.C#编译器可以注意到这一点,只创建一次并将其缓存到某个地方,以便将来调用该方法吗?或者它每次只是从头开始创建?我知道它可能是包含类的一个字段,但是对于我这样的东西来说似乎更适合我使用它的方法.

Ore*_*ost 7

每次C#编译器应该如何知道它是"相同的"字典?您每次都明确地创建一个新的字典.C#不支持静态局部变量,因此您必须使用字段.即使没有其他方法使用该字段,也没有错.

如果C#编译器做了那样的事情会很糟糕.如果变量的构造函数使用随机输入怎么办?:)


Jon*_*eet 7

简答:不.

稍微长一点的答案:我相信它会缓存从lambda表达式创建委托的结果,该表达式不捕获任何东西(包括"this"),但这是一个非常特殊的情况.

更正代码的正确方法:为字典声明私有静态只读变量.

private static readonly Dictionary<Type,Action> Actions = 
    new Dictionary<Type, Action>()
{
    { typeof(StringBuilder), () => ... },
    { typeof(DateTime), () => ... },
}

void TakeAction(Type type)
{
    Actions[type].Invoke();
}
Run Code Online (Sandbox Code Playgroud)