通过字符串获取C#动态属性的值
我想使用字符串访问 dynamic
c# 属性的值:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" } ;
如果我只有“value2”作为字符串,如何获取 d.value2 (“随机”)的值?在 javascript 中,我可以执行 d["value2"] 来访问值(“随机”),但我不确定如何使用 c# 和反射来执行此操作。我最接近的是:
d.GetType().GetProperty("value2")
...但我不知道如何从中获取实际值。
一如既往,感谢您的帮助!
I'd like to access the value of a dynamic
c# property with a string:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
How can I get the value of d.value2 ("random") if I only have "value2" as a string? In javascript, I could do d["value2"] to access the value ("random"), but I'm not sure how to do this with c# and reflection. The closest I've come is this:
d.GetType().GetProperty("value2")
... but I don't know how to get the actual value from that.
As always, thanks for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
一些解决方案不适用于我从 json 字符串获取的 valuekind 对象,可能是因为我的代码中没有与我从 json 字符串获取的对象类似的具体类型,所以我是如何进行的这
对我有用
Some of the solutions were not working with a valuekind object that I obtained from a json string, maybe because I did not have a concrete type in my code that was similar to the object that I would obtain from the json string, so how I went about it was
That worked for me
在.Net core 3.1中你可以这样尝试
In .Net core 3.1 you can try like this
将
dynamic
与Newtonsoft.Json.JsonConvert.DeserializeObject
结合使用:示例:
https://dotnetfiddle.net/XGBLU1
Use
dynamic
withNewtonsoft.Json.JsonConvert.DeserializeObject
:Sample:
https://dotnetfiddle.net/XGBLU1
与接受的答案类似,您也可以尝试
GetField
而不是GetProperty
。d.GetType().GetField("value2").GetValue(d);
根据实际
Type
的实现方式,当 GetProperty() 不起作用时,这可能会起作用甚至可以更快。Similar to the accepted answer, you can also try
GetField
instead ofGetProperty
.d.GetType().GetField("value2").GetValue(d);
Depending on how the actual
Type
was implemented, this may work when GetProperty() doesn't and can even be faster.如果您有一个动态变量,例如 DapperRow,您可以首先构建一个 ExpandoObject,然后将 Expando 转换为 IDictionary。从那时起,通过属性名称获取值是可能的。
辅助方法 ToExpandoObject:
示例用法,我在示例中以粗体标记了允许我们访问的转换,我用 ** 字母标记了重要位:
在我的示例中,我在动态对象 DapperRow 中查找属性值,并且首先将 Dapper 行转换为 ExpandoObject 并将其转换为字典属性包,如此处其他答案中所示和提到的。
我的示例代码是我正在开发的 Dapper 扩展的 InsertMany 方法,我想在批量插入后获取多个 id。
In case you have a dynamic variable such as a DapperRow for example you can first build up an ExpandoObject, then cast the Expando into an IDictionary<string, object>. From then on, getting a value via the name of a property is possible.
Helper method ToExpandoObject:
Sample usage, I have marked in bold the casting which gives us access in the example, I have marked the important bits with the ** letters:
In my example, I look up a property value inside a dynamic object DapperRow and first convert the Dapper row into an ExpandoObject and cast it into a dictionary property bag as shown and mentioned in other answers here.
My sample code is the InsertMany method for Dapper extension I am working on, I wanted to grab hold of the multiple ids here after the batch insert.
内部存储过程:
C# 代码:
这是带有值的调试窗口,我们将其作为对象获取,因此将其转换为 int。
Inside Stored Procedure:
C# Code:
Here is the debugging window with value, we are getting it as an object so convert it to int.
获得
PropertyInfo
(来自GetProperty
)后,您需要调用GetValue
并传入要从中获取值的实例。在你的情况下:Once you have your
PropertyInfo
(fromGetProperty
), you need to callGetValue
and pass in the instance that you want to get the value from. In your case:添加对 Microsoft.CSharp 的引用。也适用于动态类型以及私有属性和字段。
编辑:虽然此方法有效,但 Microsoft.VisualBasic.dll 程序集中的方法几乎快 20 倍:
Add reference to Microsoft.CSharp. Works also for dynamic types and private properties and fields.
Edit: While this approach works, there is almost 20× faster method from the Microsoft.VisualBasic.dll assembly:
Dynamitey 是一个开源
.net std
库,您可以这样称呼它dynamic
关键字,但使用字符串作为属性名称,而不是编译器为您执行此操作,最终会变成 等于反射速度(几乎没有使用dynamic关键字那么快,但这是由于动态缓存的额外开销,编译器静态缓存)。Dynamitey is an open source
.net std
library, that let's you call it like thedynamic
keyword, but using the a string for the property name rather than the compiler doing it for you, and it ends up being equal to reflection speedwise (which is not nearly as fast as using the dynamic keyword, but this is due to the extra overhead of caching dynamically, where the compiler caches statically).获取属性的
setter
和getter
的最简单方法,适用于任何类型,包括dynamic
和ExpandoObject
> 是使用FastMember
这也恰好是最快的方法(它使用发射)。您可以获取基于给定类型的
TypeAccessor
或基于给定类型实例的ObjectAccessor
。例子:
The easiest method for obtaining both a
setter
and agetter
for a property which works for any type includingdynamic
andExpandoObject
is to useFastMember
which also happens to be the fastest method around (it uses Emit).You can either get a
TypeAccessor
based on a given type or anObjectAccessor
based of an instance of a given type.Example:
大多数时候,当您请求动态对象时,您会得到一个 ExpandoObject(不在上面问题的匿名但静态类型的示例中,但您提到了 JavaScript 和我选择的 JSON 解析器 JsonFx,其中一个会生成 ExpandoObjects)。
如果您的动态实际上是 ExpandoObject,则可以通过将其强制转换为 IDictionary 来避免反射,如 http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx。
一旦转换为 IDictionary,您就可以访问 .Item 和 .ContainsKey 等有用的方法
Much of the time when you ask for a dynamic object, you get an ExpandoObject (not in the question's anonymous-but-statically-typed example above, but you mention JavaScript and my chosen JSON parser JsonFx, for one, generates ExpandoObjects).
If your dynamic is in fact an ExpandoObject, you can avoid reflection by casting it to IDictionary, as described at http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx.
Once you've cast to IDictionary, you have access to useful methods like .Item and .ContainsKey
GetProperty/GetValue 不适用于 Json 数据,它总是生成 null 异常,但是,您可以尝试以下方法:
使用 JsonConvert 序列化对象:
然后访问它,直接将其转换回字符串:
它可以直接应用 Convert。 ToString(request)["DynamicFieldName"],但是我还没有测试过。
The GetProperty/GetValue does not work for Json data, it always generate a null exception, however, you may try this approach:
Serialize your object using JsonConvert:
Then access it directly casting it back to string:
It may work straight applying the Convert.ToString(request)["DynamicFieldName"], however I haven't tested.
从动态文档获取属性
当
.GetType()
返回null
时,尝试以下操作:To get properties from dynamic doc
when
.GetType()
returnsnull
, try this:返回一个 PropertyInfo 对象。
那么就这样做
returns a PropertyInfo object.
So then do
这是我获取动态属性值的方法:
This is the way i ve got the value of a property value of a dinamic: