为什么可以';t我索引到ExpandoObject中

本文关键字:索引 ExpandoObject 为什么 | 更新日期: 2023-09-27 18:29:26

今天在研究C#动态时,有些事情让我大吃一惊(我从来没有经常使用它们,但最近我一直在尝试Nancy web框架)。我发现我不能这样做:

dynamic expando = new ExpandoObject();
expando.name = "John";
Console.WriteLine(expando["name"]);

最后一行抛出异常:

无法将带有[]的索引应用于类型为的表达式"System.Dynamic.ExpandoObject"

我理解错误信息,但我不明白为什么会发生这种情况。我看过ExpandoObject的文档,它显式地实现了IDictionary<,>,因此有了this.[index]方法(MSDN)。为什么我不能叫它?

当然,没有什么可以阻止我手动将ExpandoObject下转换到字典中,然后对其进行索引,但这有点违背重点;它也没有解释Expando是如何隐藏其一个接口的方法的。

这是怎么回事?

为什么可以';t我索引到ExpandoObject中

Expando如何能够隐藏其一个接口的方法。

因为正如您在文档中正确发现的那样,索引器是一个显式接口实现。来自显式接口实现教程:

实现接口的类可以显式实现该接口的成员。当显式实现成员时,不能通过类实例访问它,只能通过接口的实例访问。

这意味着您必须将引用转换为接口才能访问它:

((IDictionary<String, Object>)expando)["name"]

使用此工厂类创建ExpandoObjects!然后使用HasProperty("道具名称")或GetValue("道具名")

void Main()
{
    dynamic _obj = ExpandoObjectFactory.Create();
    if (_obj.HasProperty("Foo") == false)
    {
        _obj.Foo = "Foo";
    }
    Console.WriteLine(_obj); // Foo;
    object bar = _obj.GetValue("Bar");
    Console.WriteLine(bar); // null
}
public static class ExpandoObjectFactory
{
    public static ExpandoObject Create()
    {
        dynamic expandoObject = new ExpandoObject();
        expandoObject.HasProperty = new Func<string, bool>((string name) => ((IDictionary<string, object>)expandoObject).ContainsKey(name));
        expandoObject.GetValue = new Func<string, object>(delegate (string name)
        {
            ((IDictionary<string, object>)expandoObject).TryGetValue(name, out object value);
            return value;
        });
        return expandoObject;
    }
}