从IDictionary转换为通用IDictionary的最佳方式

Geo*_*uer 12 c# generics

我有一个IDictionary字段,我希望通过IDictionary<string, dynamic>转换类型的属性公开这个字段非常困难,因为我不知道.Cast<>()IDictionary的内容.

最好的我有:

IDictionary properties;
protected virtual IDictionary<string, dynamic> Properties {
  get { 
        return _properties.Keys.Cast<string>()
              .ToDictionary(name=>name, name=> _properties[name] as dynamic); 
      }
    }
Run Code Online (Sandbox Code Playgroud)

Ran*_*pho 6

如果底层类型IDictionary没有实现IDictionary<string, dynamic>,则无法强制转换对象,句点.如果是这样,一个简单的演员(IDictionary<string, dynamic>)localVar就足够了.

如果不是,您可以做两件事:

  1. 复制IDictionary到您的通用类型.
  2. 构建一个Adapter类,它接受IDictionary作为依赖项并实现所需的通用IDictionary,将调用从一个映射到另一个.

编辑:您刚刚发布的示例代码将在每次调用时复制字典!我将稍后使用一些建议的代码进行编辑.

选项1

您的示例代码方法作为复制数据的方法是可靠的,但副本应该被缓存,或者您要复制很多次.我建议你把实际的翻译代码放到一个单独的方法中,并在第一次使用时从你的属性中调用它.例如:

private IDictionary dataLayerProperties; 
private IDictionary<string, dynamic> translatedProperties = null;
protected virtual IDictionary<string, dynamic> Properties
{
    if(translatedProperties == null)
    {
        translatedProperties = TranslateDictionary(dataLayerProperties);        
    }  
    return translatedProperties;
}

public IDictionary<string, dynamic> TranslateDictionary(IDictionary values)
{
    return values.Keys.Cast<string>().ToDictionary(key=>key, key => values[key] as dynamic);            
}
Run Code Online (Sandbox Code Playgroud)

现在,这种方法有明显的缺点......如果需要刷新dataLayerProperties怎么办?你必须再次将translatedProperties设置为null,等等.

选项2

这是我的首选方法.

public class TranslatedDictionary : IDictionary<string, dynamic>
{
    private IDictionary Original = null;

    public TranslatedDictionary(IDictionary original)
    {
        Original = original;
    }
    public ICollection<string> Keys
    {
        get
        {
            return Original.Keys.Cast<string>().ToList();
        }
    }

    public dynamic this[string key]
    {
        get
        {
            return Original[key] as dynamic;
        }
        set
        {
            Original[key] = value;
        }
    }
    // and so forth, for each method of IDictionary<string, dynamic>
}

//elsewhere, using your original property and field names:
Properties = new TranslatedDictionary(properties);
Run Code Online (Sandbox Code Playgroud)

现在,有明显的缺点,以这种方式为好,最明显的是事实,Keys(和值和其他任何返回ICollectionIDictionary必须返回一个新的数组,每个呼叫.但是,这仍然允许最灵活的方法,因为它确保数据始终是最新的.