我有一个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)
如果底层类型IDictionary
没有实现IDictionary<string, dynamic>
,则无法强制转换对象,句点.如果是这样,一个简单的演员(IDictionary<string, dynamic>)localVar
就足够了.
如果不是,您可以做两件事:
IDictionary
到您的通用类型.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
(和值和其他任何返回ICollection
上IDictionary
必须返回一个新的数组,每个呼叫.但是,这仍然允许最灵活的方法,因为它确保数据始终是最新的.