I’ve got a standard ‘dynamic dictionary’ type class in 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);
}
}
Now I call it, as follows:
static void Main(string[] args)
{
dynamic d = new Bucket();
d.Name = "Orion"; // 2 RuntimeBinderExceptions
Console.WriteLine(d.Name); // 2 RuntimeBinderExceptions
}
The app does what you’d expect it to, but the debug output looks like this:
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
Any attempt to access a dynamic member seems to output a RuntimeBinderException to the debug logs. While I’m aware that first-chance exceptions are not a problem in and of themselves, this does cause some problems for me:
-
I often have the debugger set to “break on exceptions”, as I’m writing WPF apps, and otherwise all exceptions end up getting converted to a
DispatcherUnhandledException, and all the actual information you want is lost. WPF sucks like that. -
As soon as I hit any code that’s using
dynamic, the debug output log becomes fairly useless. All the useful trace lines that I care about get hidden amongst all the uselessRuntimeBinderExceptions
Is there any way I can turn this off, or is the RuntimeBinder unfortunately just built like that?
Thanks, Orion
Whenever a property on a dynamic object is resolved, the runtime tries to find a property that is defined at compile time. From DynamicObject doco:
RuntimeBinderExceptionis thrown whenever the runtime cannot find a statically defined property(i.e. what would be a compiler error in 100% statically typed world). From MSDN articleIt is interesting that if you use
ExpandoObject, you only get one exception when trying to use the property:Perhaps
ExpandoObjectcould be an alternative? If it’s not suitable you’ll need to look into implementingIDynamicMetaObjectProvider, which is howExpandoObjectdoes dynamic dispatch. However, it is not very well documented and MSDN refers you to the DLR CodePlex for more info.