【问题标题】:ExpandoObject object and GetProperty()ExpandoObject 对象和 GetProperty()
【发布时间】:2015-08-31 13:16:45
【问题描述】:

我正在尝试编写一个通用实用程序,以便从外部 .NET 中通过 COM 使用(/skip long story)。无论如何,我正在尝试向 ExpandoObject 添加属性,我需要将 PropertyInfo 结构返回以传递给另一个例程。

using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Reflection;

public class ExpandoTest
{
    public string testThis(string cVariable)
    {
        string cOut = "";

        ExpandoObject oRec = new ExpandoObject { };
        IDictionary<string, object> oDict = (IDictionary<string, object>)oRec;

        oDict.Add(cVariable, "Test");

        Trace.WriteLine(cVariable);
        Trace.WriteLine(oDict[cVariable]);

        PropertyInfo thisProp = oRec.GetType().GetProperty(cVariable);

        if (thisProp != null)
        {
            cOut= "Got a property :)";
        }

        return cOut;
    }
}

为什么我总是在 thisProp 中得到一个空值?我显然不明白,但我已经盯着它看了一天,我什么也没有。谢天谢地接受所有帮助/批评!

【问题讨论】:

  • 您正在寻找 ExpandoObject 类本身的属性。您不会为您刚刚制作的属性获得PropertyInfo(它不存在,即使dynamic 让您认为它存在)。这里没有什么神奇的。不过你可以得到PropertyDescriptor
  • 我不确定您的用例是什么,但您可能想要实现 IReflect 接口。当与 COM 互操作一起使用时,这将允许您实现自定义 IDispatch 接口。 msdn.microsoft.com/en-us/library/…
  • @LucasTrzesniewski 所有使用 ExpandoObject 的示例似乎都是这样做的,甚至在末尾添加 .GetValue(oRec, null) (例如)。 @shf301 我只是通过 COM 接口传递字符串参数(嗯,字符串包含 XML 但仍然是字符串)。它用于实现用户可配置的文本文件导入器(csv、制表符分隔等),但所有复杂性都包含在 .NET 代码中。它只是没有明确定义的数据。我需要建立一个与 CsvHelper 一起使用的动态映射,并且我需要将其传递给 PropertyInfo 结构(使用我拥有的示例)
  • @LucasTrzesniewski 你是对的。我回过头来查看我翻阅过的所有文章,它们是动态使用的示例,而不是 Expando。我希望它以某种方式装饰它以将它们添加为“虚拟”属性,但可惜不是。感谢您的帮助。

标签: c# dynamic expandoobject


【解决方案1】:

虽然使用ExpandoObject 看起来您可以在运行时添加属性,但实际上在CLR 级别不会这样做。这就是为什么使用反射来获取您在运行时添加的属性不起作用的原因。

ExpandoObject 视为将字符串映射到对象的字典会有所帮助。当您将ExpandoObject 视为dynamic 变量时,任何属性调用都会被路由到该字典。

dynamic exp = new ExpandoObject();
exp.A = "123";

实际调用比较复杂,涉及到DLR,但是效果和写是一样的

((IDictionary<string, object>)exp)["A"] = "123";

这也仅在使用dynamic 时有效。上述代码的强类型版本会导致编译时错误。

var exp = new ExpandoObject();
exp.A = "123"; // compile-time error

ExpandoObject的实际实现可以参考here

【讨论】:

  • 谢谢@dirk。我必须找到另一种方法来定义映射。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-31
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 2020-06-16
相关资源
最近更新 更多