【问题标题】:C#: Is there a clean pattern for finding the right object combined with using?C#:是否有一个干净的模式来找到正确的对象并结合使用?
【发布时间】:2016-08-15 07:23:24
【问题描述】:

我想要一个干净/紧凑的模式,它是异常安全的,并且会正确处理rulesKey,即使有东西被抛出。 using 似乎不可能做到这一点(除非可能有 4 个 usings,但这似乎太冗长并且打开了我什至可能不需要打开的额外资源)。让我明白的是,这在 C++ 中是如此直接/容易。有好的解决办法吗?

{
    RegistryKey rulesKey = null;
    rulesKey = rulesKey ?? Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Company\\Internal\\Product");
    rulesKey = rulesKey ?? Registry.LocalMachine.OpenSubKey("Software\\Company\\Company\\Internal\\Product");
    rulesKey = rulesKey ?? Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Company\\Product");
    rulesKey = rulesKey ?? Registry.LocalMachine.OpenSubKey("Software\\Company\\Product");

    // Code using rulesKey, might throw

    rulesKey.Close();
}

【问题讨论】:

    标签: c# registry using null-coalescing-operator


    【解决方案1】:

    你可以使用

    using (RegistryKey rulesKey = Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Company\\Internal\\Product")
                                    ?? Registry.LocalMachine.OpenSubKey("Software\\Company\\Company\\Internal\\Product")
                                    ?? Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Company\\Product")
                                    ?? Registry.LocalMachine.OpenSubKey("Software\\Company\\Product"))
    {
        //use rulesKey here
    }
    

    自从

    using 语句可确保调用 Dispose,即使在您调用对象上的方法时发生异常也是如此。您可以通过将对象放在 try 块中,然后在 finally 块中调用 Dispose 来获得相同的结果;事实上,这就是编译器翻译 using 语句的方式。 MSDN

    【讨论】:

    • 如果没有钥匙可以打开怎么办?
    • 因为OpenSubKey如果失败则返回null,那么rulesKey如果都失败则为null。
    • 如果没有打开任何键,则为空,至少对于using 语句是安全的
    • 谢谢,不知道为什么我没有想到这个!
    【解决方案2】:

    您还可以执行以下操作。该示例是硬编码的,但您可以轻松地从文件或数据库或其他任何内容加载路径。这将允许您添加额外的键而不会使 using 语句膨胀。它还可以防止受限访问

    List<string> keyPaths = GetKeyPaths();
    private void DoStuff()
    {        
        // key is disposed when leaving using block
        using(var key = OpenFirstAvailableKey())
        {
            if(key == null)
            {
                // handle error
            }
    
            // do stuff
        }
    }
    
    private RegistryKey OpenFirstAvailableKey()
    {
        RegistryKey result = null;
        try
        {
            foreach(var key in keyPaths)
            {
                result = Registry.LocalMachine.OpenSubKey(key);
                if(result != null)
                {
                    break;
                }
            }    
        }
        catch (System.Exception)
        {
            // handle or throw        
            throw;
        }
    
        return result;
    }
    
    private List<string> GetKeyPaths()
    {
        List<string> paths = new List<string>();
        // Load from db or file or whatever...or just hardcode
        paths.Add("Software\\Wow6432Node\\Company\\Internal\\Product");
        paths.Add("Software\\Company\\Company\\Internal\\Product");
        paths.Add("Software\\Wow6432Node\\Company\\Product");
        paths.Add("Software\\Company\\Product");
    
        return paths;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 2022-08-11
      • 2011-01-01
      相关资源
      最近更新 更多