Mucha oportunidad de Microsoft.CSharp.RuntimeBinderExceptions lanzado cuando se trata de dinámicas

Tengo una clase de tipo “diccionario dynamic” estándar en C # –

class Bucket : DynamicObject { readonly Dictionary m_dict = new Dictionary(); 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í:

 Se produjo una primera excepción de tipo 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' en Microsoft.CSharp.dll
 Se produjo una primera excepción de tipo 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' en Microsoft.CSharp.dll
 'ScratchConsoleApplication.vshost.exe' (Administrado (v4.0.30319)): cargado 'Asamblea de DynamicMethods alojado de forma anónima'
 Se produjo una primera excepción de tipo 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' en Microsoft.CSharp.dll
 Se produjo una primera excepción de tipo 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' en Microsoft.CSharp.dll

Cualquier bash de acceder a un miembro dynamic 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:

  1. 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í.

  2. 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útiles RuntimeBinderException s

¿Hay alguna forma de que pueda apagar esto o desafortunadamente el RuntimeBinder está construido así?

Gracias, Orion

Cada vez que se resuelve una propiedad en un objeto dynamic, el tiempo de ejecución intenta encontrar una propiedad que se define en tiempo de comstackció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 dynamic (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 comstackció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 comstackció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 dynamic. Sin embargo, no está muy bien documentado y MSDN lo remite al DLP CodePlex para obtener más información.

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.