2

我有一个DynamicObject并且我希望它可以转换为 IDictionary,与ExpandoObject. 例如,将 ExpandoObject 强制转换为 IDictionary 是完全有效的:

dynamic ex = new ExpandoObject ();
ex.Field = "Foobar";
IDictionary<string, object> dict = ex as IDictionary<string, object>;
Console.WriteLine (dict["Field"]);

现在我尝试将它实现到我自己的 DynamicObject 中:

public class MyDynamicObject : DynamicObject
{
    public Dictionary<string, object> members = new Dictionary<string, object> ();

    public override bool TryGetMember (GetMemberBinder binder, out object result)
    {
        if (members.ContainsKey (binder.Name)) {
            result = members[binder.Name];
            return true;
        }
        else {
            result = null;
            return false;
        }
    }
    public override bool TrySetMember (SetMemberBinder binder, object value)
    {
        this.members.Add (binder.Name, value);
        return true;
    }
    public static implicit operator IDictionary<string, object> (MyDynamicObject mydo) 
    {
        return (IDictionary<string, object>) mydo.members;
    }
}

但是编译器将public static implicit operator IDictionary<string, object>在线失败,并给出错误:“无法转换为接口类型或从接口类型转换”。如果我将隐式运算符更改为 Dictionary,我可以将 MyDynamicObject 转换为 Dictionary 而不会出现任何问题,但不是 IDictionary。

ExpandoObject 如何做到这一点?

4

3 回答 3

8

ExpandoObject简单地实现IDictionary<string, object>.

如果您想拥有相同的行为,您还需要实现此接口并将所有调用委托给您的members字段。

像这样的东西:

public class MyDynamicObject : DynamicObject, IDictionary<string, object>
{
    public Dictionary<string, object> members = new Dictionary<string, object>();

    public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
    {
        return members.GetEnumerator();
    }

    public void Add(KeyValuePair<string, object> item)
    {
        members.Add(item.Key, item.Value);
    }

    // ...
}
于 2012-08-31T07:52:30.900 回答
0

DLR 不会询问演员表操作员 - 因此这不起作用。

您可以继承IDictionary或覆盖该TryConvert方法。

由于实现IDictionary需要实现或删除大量操作,因此您可能会发现TryConvert路由实际上更容易实现;不利的一面是,在您的实现中,TryConvert您几乎肯定会在每次调用它时生成一个新的字典实例(除非您缓存结果使其保持最新),因此它可能会对性能造成额外影响

于 2012-08-31T07:54:42.110 回答
0

它在 C# 规范中定义:

如果满足以下所有条件,则允许类或结构声明从源类型 S 到目标类型 T 的转换:

  • ...
  • S 和 T 都不是objectinterface -type

请参阅此堆栈溢出答案。

于 2012-08-31T07:55:59.520 回答