55

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:

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

  2. 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 useless RuntimeBinderExceptions

Is there any way I can turn this off, or is the RuntimeBinder unfortunately just built like that?

Thanks, Orion

Orion Edwards
  • 121,657
  • 64
  • 239
  • 328
  • 3
    This occurs when just using the MVC 3 ViewBag under normal working circumstances. It's annoying and disconcerting since exceptions are expensive. – Luke Puplett Nov 28 '11 at 17:30
  • I'm new to .net world, I'm developing webapp for travel agency using travelport api. API is SOAP based with .wsdl & .xsd files. I created proxy classes using vs015 inbuilt tool. When I use those proxy classes, all flow is fine and the api gives response, but in vs015 'Output window' I get, "Exception thrown: 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' in Microsoft.CSharp.dll", what is reason behind this exception & is this normal vs015 behavior. Thank you all. Although this is not a place to post this type of comment, I thought, I could approach you guys for help from here.SORRY. – codemilan Nov 03 '17 at 09:23
  • 3
    @codemilan You have the same question that I did 7 years ago in 2010... scroll down and look at the two answers, basically these Exceptions are normal behaviour shown when using something built using the `dynamic` keyword in C#... It seems like a poor design decision on part of the C# people at microsoft, but that's the way it is – Orion Edwards Nov 05 '17 at 10:51
  • Thank you, alot @OrionEdwards – codemilan Nov 06 '17 at 07:29

2 Answers2

31

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:

You can also add your own members to classes derived from the DynamicObject class. If your class defines properties and also overrides the TrySetMember method, the dynamic language runtime (DLR) first uses the language binder to look for a static definition of a property in the class. If there is no such property, the DLR calls the TrySetMember method.

RuntimeBinderException is 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 article

...RuntimeBinderException represents a failure to bind in the sense of a usual compiler error...

It is interesting that if you use ExpandoObject, you only get one exception when trying to use the property:

dynamic bucket = new ExpandoObject();
bucket.SomeValue = 45;
int value = bucket.SomeValue; //<-- Exception here

Perhaps ExpandoObject could be an alternative? If it's not suitable you'll need to look into implementing IDynamicMetaObjectProvider, which is how ExpandoObject does dynamic dispatch. However, it is not very well documented and MSDN refers you to the DLR CodePlex for more info.

Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
26

This was bothering me, too. I added the exception to the exceptions list so that I could deselect it. Just follow these steps:

  • From the Debug menu, select Exceptions.
  • Click the "Add..." button on the bottom right.
  • Choose "Common Language Runtime Exceptions" from the Type dropdown.
  • Type "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException" as the name.
  • Click OK.
  • The exception type will now appear on the list. Just deselect it.

I wish this setting could be saved across solutions, but I don't think it can, so you'll have to reapply this setting on every solution.

P Daddy
  • 28,912
  • 9
  • 68
  • 92
Anthony Johnston
  • 9,405
  • 4
  • 46
  • 57
  • 10
    For me, this doesn't actually turn off the debug log showing the exception. It does let me cause the debugger to break on these exceptions, but that's not what I want. I want them to stop spewing. – tig Sep 01 '13 at 20:16
  • I still not get it. did you mean we just need to ignore it when we see it output this exception in visual studio? Is that normal?? – qakmak Sep 27 '15 at 16:24
  • I needed to turn off breaking on this exception, and this helped. Thanks! – Sava B. Jan 06 '16 at 20:44
  • 2
    In Visual Studio 2015: Debug menu -> Windows -> Exception settings (Ctrl+Alt+E) – Kasper Jensen Apr 19 '16 at 07:01