Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should an interface-based method invoke that uses "dynamic" still obey C# method resolution rules?

Tags:

c#

dynamic

As I understand it, each language can have it's own dynamic handler, so that the appropriate rules are applied. I'm unsure if the following is correct/incorrect; thoughts?

Scenario: two interfaces (one implements the other) with some methods:

public interface IA {
    void Bar(object o);
}
public interface IB : IA {
    void Foo(object o);
}

and a basic implementation:

public class B : IB {
    public void Foo(object o) { Console.WriteLine("Foo"); }
    public void Bar(object o) { Console.WriteLine("Bar"); }
}

Now, with normal C# (no dynamic), we can access methods of IA from a target of type IB:

IB b = new B();
var o = new { y = "z" };
b.Foo(o.y); // fine
b.Bar(o.y); // fine

Now let's deliberately add some dynamic to the arguments, which makes the entire invoke use dynamic processing (as in the general case this could impact overload resolution, although it won't here):

IB b = new B();
dynamic x = new {y = "z"};
b.Foo(x.y); // fine
b.Bar(x.y); // BOOM!

Which fails with the RuntimeBinderException:

'IB' does not contain a definition for 'Bar'

Now, what it says is entirely correct in as much as IB does not have a Bar method. However, as illustrated in the first example: under normal C# rules would expect that since the declaration type of the target is an interface (IB), the other interfaces known to be implemented (i.e. IA) are checked as part of overload resolution.

So: is this a bug? Or am I misreading it?

like image 758
Marc Gravell Avatar asked Mar 23 '12 10:03

Marc Gravell


1 Answers

This is a well known limitation of the binder, asked about several times at SO and the subject of this feedback article. I'll quote Microsoft's answer:

This was an area we explicitly scoped out due to time when shipping C# 4.0 and we'd love to revisit this. This specific case of ISet/IList methods that are actually defined on ICollection is the most visible place where not digging up through parent interfaces unnecessarily limits the reach of dynamic binding in C#.

We hope to add such support soon, though this issue currently falls just below our bug triage cut line. We're marking the issue Won't Fix to indicate that we're not currently tracking to fix this issue in the next release of Visual Studio. We'll reactivate this bug over the next year if we get further than expected through our bug triage list, or if we revisit the bug for the following release.

Which didn't happen yet, afaik. The article doesn't have a lot of votes.

like image 88
Hans Passant Avatar answered Nov 19 '22 18:11

Hans Passant