Search code examples
c#overloadingfactory

Method overloading & inheritance - how to address to the right method?


I have the following Factory:

public class ChildFactory : IChildFactory {
    public Child? GetChild(ChildType childType)
    {
        switch (childType)
        {
            case ChildType.Boy:
                return new BoyChild() { };
            case ChildType.Girl:
                return new GirlChild() { };
            case ChildType.Undecided:
                return new UndecidedChild() { };
            default:
                return null;
         }
    }
}

Whenever I pass through a ChildType in order to generate a Child, I get back the right instance of a child:

Child? child = _childFactory.GetChild((ChildType)Enum.Parse(typeof(ChildType), childDto.Type));

Seems like at this point, child is of the correct type (Let's say BoyChild). Now I want to dynamically validate each of the child types separately using method overloading. Here's the interface:

public interface IChildValidator
    {
        public ValidationResult Validate(BoyChild child);
        public ValidationResult Validate(GirlChild child);
        public ValidationResult Validate(UndecidedChild policy);
    }

But whenever I try to use it in the method above, I get the error CS1503: Cannot convert from 'Child' to 'BoyChild'.

I guess I should somehow declare child differently, saying "It can be any of the child types", but I don't know how to do that.

Thanks in advance.


Solution

  • Overload Resolution happens at compile time. The C# compiler uses the static type of an argument to find the best overload. Since you are calling the method with an argument of type Child, the compiler does not find a matching overload. None of the three overloads has a parameter of type Child. There is no implicit conversion from Child to BoyChild, GirlChild or UndecidedChild. You can assign a derived class to a base class, but not the other way around.

    The way to go, is to use polymorphy, i.e., to add an abstract Validate method to the (abstract) Child class (unless you can provide a standard implementation in the base class). The derived classes then must override this method and provide an implementation. At runtime, Dynamic dispatch will then call the right implementation.