无法通过反射获取动态属性
本文关键字:获取 动态 属性 反射 | 更新日期: 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解析器构建的。