Я хотел бы получить доступ к значению dynamic
свойства c # с помощью строки:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
Как я могу получить значение d.value2 ("random"), если у меня есть только "value2" как строка? В javascript я мог бы сделать d ["value2"] для доступа к значению ("random"), но я не уверен, как это сделать с помощью c # и отражения. Самое близкое, что я пришел, это:
d.GetType().GetProperty("value2")
... но я не знаю, как получить реальную стоимость от этого.
Как всегда, спасибо за вашу помощь!
Ответы:
Как только вы получите свой
PropertyInfo
(отGetProperty
), вам нужно вызватьGetValue
и передать экземпляр, из которого вы хотите получить значение. В твоем случае:источник
'd.GetType().GetProperty("value2").GetValue(d)' threw an exception of type 'System.Reflection.TargetInvocationException' dynamic {System.Reflection.TargetInvocationException}
в окне с этим ..?new {}
создается реальный анонимный тип с определенными свойствами, вызов GetType / GetProperty имеет смысл, но как насчет ExpandoObject, который, если вы вызовете GetType, вы получите тип, который имеет свойства ExpandoObject, но не обязательно его динамические свойства.Добавить ссылку на Microsoft.CSharp. Работает также для динамических типов и частных свойств и полей.
Изменить : хотя этот подход работает, есть почти в 20 раз более быстрый метод из сборки Microsoft.VisualBasic.dll :
источник
d
в вопросе).CallSite
код сCallByName
кодом, сравнивали ли вы их при кэшированииCallSite
экземпляра? Я подозреваю, что стоимость вашего первого метода - это почти чисто активация,Binder
аCallSite
не вызовTarget()
Dynamitey - это
.net std
библиотека с открытым исходным кодом , которая позволяет вам называть ее какdynamic
ключевое слово, но используя строку для имени свойства, а не компилятор, который делает это за вас, и в итоге она оказывается равной отражению по скорости (что не так быстро с использованием ключевого слова dynamic, но это связано с дополнительными издержками динамического кэширования, когда компилятор статически кэшируется).источник
Самый простой метод для получения как a, так
setter
и agetter
для свойства, которое работает для любого типа, в том числе,dynamic
иExpandoObject
заключается в использовании,FastMember
который также является самым быстрым методом (он использует Emit).Вы можете получить
TypeAccessor
основанный на заданном типе илиObjectAccessor
основанный на экземпляре заданного типа.Пример:
источник
Большую часть времени, когда вы запрашиваете динамический объект, вы получаете ExpandoObject (не в приведенном выше примере с анонимным, но статически типизированным вопросом, но вы упоминаете JavaScript, и мой выбранный JSON-анализатор JsonFx, например, генерирует ExpandoObjects).
Если ваша динамика на самом деле является ExpandoObject, вы можете избежать отражения, приведя его к IDictionary, как описано по адресу http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx .
Как только вы приведете к IDictionary, у вас есть доступ к полезным методам, таким как .Item и .ContainsKey.
источник
Int64? i = data.value; //data is ExpandoObject
бы поиск и вызывал бы неявный оператор. С другой стороны, если бы мне пришлось использовать IDictionary, чтобы проверить, существует ли поле «значение», я бы получил объект обратно, который не будет без ошибок приведен к Int64 ?.GetProperty / GetValue не работает для данных Json, он всегда генерирует нулевое исключение, однако вы можете попробовать этот подход:
Сериализуйте ваш объект с помощью JsonConvert:
Затем получите к нему доступ, приведя его обратно к строке:
Это может работать напрямую, применяя Convert.ToString (request) ["DynamicFieldName"], однако я не проверял.
источник
new JavaScriptSerializer().Deserialize<object>(json);
чтобы добраться до «свойств» так, как вы предлагаливозвращает объект PropertyInfo.
Так тогда делай
источник
GetValue(d)
необходимо, чтобыGetValue(d,null)
Вот как я получил значение свойства динамического объекта:
источник
Чтобы получить свойства из динамического документа при
.GetType()
возвратеnull
, попробуйте это:источник
В .Net core 3.1 вы можете попробовать вот так
источник
Подобно принятому ответу, вы также можете попробовать
GetField
вместоGetProperty
.d.GetType().GetField("value2").GetValue(d);
В зависимости от того, как
Type
был реализован факт , это может работать, когда GetProperty () не работает и может даже быть быстрее.источник