reflection - español - static dynamic c#
Agregando miembros dinámicamente a un objeto dinámico (4)
Lo que quiere es similar a las funciones getattr / setattr de Python. No hay una forma equivalente incorporada de hacerlo en C # o VB.NET. La capa externa del DLR (que se envía con IronPython e IronRuby en Microsoft.Scripting.dll) incluye un conjunto de API de alojamiento que incluye una API ObjectOperations que tiene métodos GetMember / SetMember. Podría usarlos pero necesitaría la dependencia adicional del DLR y un lenguaje basado en DLR.
Probablemente, el enfoque más simple sería crear un CallSite con uno de los enlazadores de C # existentes. Puede obtener el código para esto mirando el resultado de "foo.Bar = 42" en ildasm o reflector. Pero un simple ejemplo de esto sería:
object x = new ExpandoObject();
CallSite<Func<CallSite, object, object, object>> site = CallSite<Func<CallSite, object, object, object>>.Create(
Binder.SetMember(
Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None,
"Foo",
null,
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
)
);
site.Target(site, x, 42);
Console.WriteLine(((dynamic)x).Foo);
Estoy buscando una forma de agregar miembros dinámicamente a un objeto dinámico. OK, creo que se necesita una pequeña aclaración ...
Cuando haces eso:
dynamic foo = new ExpandoObject();
foo.Bar = 42;
La propiedad Bar
se agregará dinámicamente en tiempo de ejecución. Pero el código aún se refiere "estáticamente" a Bar (el nombre "Bar" está codificado) ... ¿Qué sucede si quiero agregar una propiedad en tiempo de ejecución sin saber su nombre en el momento de la compilación?
Sé cómo hacer esto con un objeto dinámico personalizado (de hecho, publiqué sobre él hace unos meses), utilizando los métodos de la clase DynamicObject
, pero ¿cómo puedo hacerlo con cualquier objeto dinámico?
Probablemente podría usar la interfaz IDynamicMetaObjectProvider
, pero no entiendo cómo usarla. Por ejemplo, ¿qué argumento debería pasar al método GetMetaObject
? (espera una Expression
)
Y, por cierto, ¿cómo se realiza la reflexión sobre los objetos dinámicos? La reflexión "Regular" y TypeDescriptor
no muestran los miembros dinámicos ...
Cualquier idea sería apreciada !
ExpandoObject implementa IDictionary <cadena, objeto> aunque explícitamente. Lo que esto significa es que simplemente puede lanzar ExpandoObject a IDictionary <string, object> y manipular el diccionario.
dynamic foo = new ExpandoObject();
foo.Bar = 42;
food = (IDictionary<string,object>)foo;
food["Baz"] = 54
Sé que esta es una publicación bastante antigua, pero pensé en pasarle la solución a Miron Abramson sobre cómo puedes crear tu propio tipo y agregar propiedades en tiempo de ejecución, en caso de que alguien más esté buscando algo similar.
El marco de código abierto Dynamitey hará esto (disponible a través de nuget ). Encapsula mientras aún almacena en caché el sitio de llamadas y el código de encuadernación que usó @Dino-Viehland.
Dynamic.InvokeSet(foo,"Bar",42);
También puede invocar muchos otros tipos de ligantes c # .