C#:是否有一种干净的模式来查找正确的对象并结合使用

本文关键字:查找 模式 对象 结合 是否 一种 | 更新日期: 2024-10-31 00:11:46

我想要一个干净/紧凑的模式,它是异常安全的,可以正确处理rulesKey,即使有什么东西抛出。这似乎不可能用using(除非可能有 4 using 秒,但这似乎很冗长,并且打开了我甚至可能不需要打开的额外资源)。 让我明白的是,这在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#:是否有一种干净的模式来查找正确的对象并结合使用

您可以使用

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

您也可以执行以下操作。该示例是硬编码的,但您可以轻松地从文件或数据库或其他内容加载路径。这将允许您添加其他键而不会使 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;
}