无法通过反射获取动态属性

本文关键字:获取 动态 属性 反射 | 更新日期: 2023-09-27 18:26:29

动态对象是使用我正在使用的Json反序列化组件(Jil)生成的,并且我能够直接访问属性。但我事先不知道他们的名字,所以我试图通过思考来获得他们的名字。我试过这样做:

var props = myDynObj.GetType().GetProperties();

但是页面超时。在调试器中不给我任何东西,只是坐在那里什么都不做,或者什么都不告诉我。

甚至当我这样做的时候也会发生这种情况:

var t = myDynObj.GetType();

但当我这样做的时候,它是有效的:

var val = myDynObj.MyStaticValue1

只是真的不能用它做任何其他事情。你知道为什么吗?我该怎么做?

无法通过反射获取动态属性

请允许我注意:

在我开始之前,如果在解析JSON时还不知道成员,那么就不应该解析为动态对象。内置的.Net JavaScriptConverter类可以将JSON解析为IDictionary<string, object>,这对您来说会更好。

但是,如果出于某种原因仍然想使用动态对象:

如果你想坚持使用你当前的库:我不知道这个类到底是如何工作的,我并不是说这是最好的解决方案,但通过查看源代码,我发现你可以使用反射获取ObjectMembers键的列表。

Type t = typeof(JsonObject)
var fi = t.GetField("ObjectMembers", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
IEnumerable<string> keys = ((Dictionary<string, JsonObject>)fi.GetValue(obj)).Keys;


编辑:看到JsonObject实现了IDynamicMetaObjectProvider,这个问题中提到的以下方法也会对它起作用:

public static IEnumerable<string> GetMemberNames(object target, bool dynamicOnly = false)
{
    var tList = new List<string>();
    if (!dynamicOnly)
    {
       tList.AddRange(target.GetType().GetProperties().Select(it => it.Name));
    }
    var tTarget = target as IDynamicMetaObjectProvider;
    if (tTarget !=null)
    {
        tList.AddRange(tTarget.GetMetaObject(Expression.Constant(tTarget)).GetDynamicMemberNames());
    }else
    {
        if (ComObjectType != null && ComObjectType.IsInstanceOfType(target) && ComBinder.IsAvailable)
        {
            tList.AddRange(ComBinder.GetDynamicDataMemberNames(target));
        }
    }
    return tList;
} 



如果您愿意尝试其他JSON转换器:请在此处尝试此类:http://pastie.org/private/vhwfvz0pg06zmjqirtlxa我不确定我在哪里找到的(我不能赊账),但这里有一个如何使用它的例子:

// Create dynamic object from JSON string
dynamic obj = DynamicJsonConverter.CreateSerializer().Deserialize("JSON STRING", typeof(object));
// Get json value
string str = obj.someValue;
// Get list of members
IEnumerable<string> members = (IDictionary<string, object>)obj).Keys

就我个人而言,我喜欢使用第二个,它简单易用,并且是基于内置的.Net JSON解析器构建的。