user1610325
user1610325

Reputation: 313

Overloading using dynamic and inheritance

I'm having an issue where I need dynamic dispatch (or at least that's what I think it should be called) with an inheritance structure. More specifically, I would like to use dynamic dispatch so I can add more specific overloads in inherited classes. I haven't been able to find anyone with quite the same problem as mine (things I find always talk about overrides in inherited classes, I need dynamic overloading). The strongly simplified situation is as follows:

class A
{
    private void DoSpecificStuff(object a);
    private void DoSpecificStuff(SomeClass a);
}

class B<T> : A
{
    private void DoSpecificStuff(OtherClass<T> a);
}

Then inside A, I have some function that consumes fields of some class using reflection. It goes like this:

public void Consume(JetAnotherClass a)
{
    // Fetch all fieldinfo's from a and for each fieldinfo, do this:
    foreach(FieldInfo info in a's fieldinfo's...)
            DoSpecificStuff((dynamic)fieldInfo.GetValue(a))
}

The calling site works as follows:

B b = new B();
b.Consume(new JetAnotherClass()); 

Now, every time the fieldInfo.GetValue(a) finds an instance of SomeClass, the desired overloaded function is being called with SomeClass as formal parameter. But when an instance of OtherClass<>T> is returned, it is DoSpecificStuff(object a) that gets called instead of DoSpecificStuff(OtherClass<>T> a).

Why does my dynamic dispatch work perfectly within one class, but breaks when another class offers more overloads that should be dynamically dispatched on? Doesn't the dynamic dispatch start by looking inside the top-most instance, which is of type B?

PS: replacing private by (virtual) protected or anything like that doesn't help. In fact, it's way weirder that using private does work for the overloads inside A, since we're calling DoSpecificStuff with an implicit this parameter of type B.

Upvotes: 1

Views: 201

Answers (1)

Anders Abel
Anders Abel

Reputation: 69260

I think that you are confusing to separate mechanisms:

  • Polymorphism - or the ability to runtime call a function in a sub class, even though the reference is of base class type.
  • Overload resolution that (normally, without dynamic) is a compile time resolution of the most specific matching function.

When you are using dynamic to defer the overload resolution to runtime you are still doing an overload resolution. The Consume method is in A so it will only look in A and have no idea of that B even exists.

To get the behaviour you want, I think that you should make a separate virtual method for calling DoSpecificStuff that contains the dynamic magic. Then repeat that functionality in class B. That way an instance of B will use the method in B and find the right candidates when doing the overload resolution.

Upvotes: 1

Related Questions