Я ищу способ изменить свойства на a dynamic
Объект C# 4.0 с названием свойства, известного только во времени выполнения.
Есть ли способ сделать что-то как (ExpandoObject
просто используется в качестве примера, это могло быть любым классом, который реализует IDynamicMetaObjectProvider
):
string key = "TestKey";
dynamic e = new ExpandoObject();
e[key] = "value";
Который был бы эквивалентен:
dynamic e = new ExpandoObject();
e.TestKey = "value";
Или единственный путь, передают отражение?
Не очень легко, нет. Отражение не работает, поскольку оно предполагает модель обычного типа, которая не полный диапазон динамического
. Если вы на самом деле просто разговариваете с обычными объектами, просто используйте здесь отражение. В противном случае, я полагаю, вы можете захотеть перепроектировать код, который компилятор генерирует для базового назначения, и настроить его, чтобы иметь гибкое имя члена. Хотя я буду честен: это не очень привлекательный вариант; простой:
dynamic foo = ...
foo.Bar = "abc";
переводится как:
if (<Main>o__SiteContainer0.<>p__Site1 == null)
{
<Main>o__SiteContainer0.<>p__Site1 = CallSite<Func<CallSite, object, string, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "Bar", typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) }));
}
<Main>o__SiteContainer0.<>p__Site1.Target(<Main>o__SiteContainer0.<>p__Site1, foo, "abc");
Если вам нужен подход, который работает как для динамических, так и для нединамических объектов: FastMember удобен для этого и работает на уровне типа или объекта:
// could be static or DLR
var wrapped = ObjectAccessor.Create(obj);
string propName = // something known only at runtime
Console.WriteLine(wrapped[propName]);
доступен на Nuget и сильно оптимизирован как для динамических, так и для нединамических сценариев.