c# - español - Mucha oportunidad de Microsoft.CSharp.RuntimeBinderExceptions lanzado cuando se trata de dinámicas
static dynamic c# (2)
Cada vez que se resuelve una propiedad en un objeto dinámico, el tiempo de ejecución intenta encontrar una propiedad que se define en tiempo de compilación. Desde DynamicObject doco:
También puede agregar sus propios miembros a clases derivadas de la clase DynamicObject. Si su clase define propiedades y también anula el método TrySetMember, el tiempo de ejecución de lenguaje dinámico (DLR) primero usa el enlace de idioma para buscar una definición estática de una propiedad en la clase. Si no existe tal propiedad, el DLR llama al método TrySetMember.
RuntimeBinderException
se lanza siempre que el tiempo de ejecución no pueda encontrar una propiedad estáticamente definida (es decir, qué sería un error de compilación en un mundo 100% estáticamente estátizado). Del artículo de MSDN
... RuntimeBinderException representa una falla al enlazar en el sentido de un error de compilación habitual ...
Es interesante que si usa ExpandoObject
, solo obtiene una excepción cuando intenta usar la propiedad:
dynamic bucket = new ExpandoObject();
bucket.SomeValue = 45;
int value = bucket.SomeValue; //<-- Exception here
Quizás ExpandoObject
podría ser una alternativa? Si no es adecuado, tendrá que considerar la implementación de IDynamicMetaObjectProvider
, que es cómo ExpandoObject
realiza el envío dinámico. Sin embargo, no está muy bien documentado y MSDN lo remite al DLP CodePlex para obtener más información.
Tengo una clase de tipo "diccionario dinámico" estándar en C # -
class Bucket : DynamicObject
{
readonly Dictionary<string, object> m_dict = new Dictionary<string, object>();
public override bool TrySetMember(SetMemberBinder binder, object value)
{
m_dict[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return m_dict.TryGetValue(binder.Name, out result);
}
}
Ahora lo llamo, como sigue:
static void Main(string[] args)
{
dynamic d = new Bucket();
d.Name = "Orion"; // 2 RuntimeBinderExceptions
Console.WriteLine(d.Name); // 2 RuntimeBinderExceptions
}
La aplicación hace lo que esperaría, pero la salida de depuración se ve así:
A first chance exception of type ''Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'' occurred in Microsoft.CSharp.dll A first chance exception of type ''Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'' occurred in Microsoft.CSharp.dll ''ScratchConsoleApplication.vshost.exe'' (Managed (v4.0.30319)): Loaded ''Anonymously Hosted DynamicMethods Assembly'' A first chance exception of type ''Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'' occurred in Microsoft.CSharp.dll A first chance exception of type ''Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'' occurred in Microsoft.CSharp.dll
Cualquier intento de acceder a un miembro dinámico parece generar una RuntimeBinderException
en los registros de depuración. Si bien soy consciente de que las excepciones de primera oportunidad no son un problema en sí mismas, esto me causa algunos problemas:
A menudo tengo el depurador configurado para "romper excepciones", mientras estoy escribiendo aplicaciones WPF, y de lo contrario todas las excepciones terminan convirtiéndose en una
DispatcherUnhandledException
, y se pierde toda la información real que desea. WPF es una mierda así.Tan pronto como toco un código que usa
dynamic
, el registro de salida de depuración se vuelve bastante inútil. Todas las líneas de rastreo útiles que me importan se ocultan entre todas las inútilesRuntimeBinderException
s
¿Hay alguna forma de que pueda apagar esto o desafortunadamente el RuntimeBinder
está construido así?
Gracias, Orion
Esto también me estaba molestando. Agregué la excepción a la lista de excepciones para poder deseleccionarla. Solo sigue estos pasos:
- Desde el menú Depurar, seleccione Excepciones.
- Haga clic en el botón "Agregar ..." en la parte inferior derecha.
- Elija "Excepciones de Common Language Runtime" en el menú desplegable Tipo.
- Escriba "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException" como el nombre.
- Haga clic en Aceptar.
- El tipo de excepción ahora aparecerá en la lista. Solo anule la selección.
Desearía que esta configuración se pudiera guardar en todas las soluciones, pero no creo que pueda, por lo que tendrá que volver a aplicar esta configuración en cada solución.