Handle generics

class Order { ... }

class OrderA : Order { ... }

class OrderB : Order { ... }

class OrderC : Order { ... }

class OrderD : Order { ... }


private Order GetOrder() { ... }

How can i have a method that dynamically casts the returned Order object to any of the specific ones:

private T GetSpecificOrder<T>(T order) : where T : Order
{
    ...
}

And i wanna call it like:

var myOrder = GetOrder();
var specificOrder = GetSpecificOrder<Order>(myOrder);
HandleOrder(specificOrder);

I want that specificOrder object is instantiated as one of the sub classes so i can call it like this:

HandleOrder(OrderA o) { ... }
HandleOrder(OrderB o) { ... }
HandleOrder(OrderC o) { ... }
HandleOrder(OrderD o) { ... }

What am I doing wrong?

Jon Skeet
people
quotationmark

It sounds like you're expecting overload resolution to occur at execution time. That doesn't happen... unless you use dynamic, which may well be the simplest solution for you:

dynamic order = GetOrder(orderId);
HandleOrder(order); // The right overload will be picked at execution time

Another alternative would be to use double-dispatch / the visitor pattern, but personally I find that a bit clunky.

Another alternative would be to make a Dictionary<Type, Action<Order>> like this:

private static readonly Dictionary<Type, Action<Order>> orderHandlers = 
    new Dictionary<Type, Action<Order>>
{
    { typeof(OrderA), order => HandleOrder((OrderA) order) },
    { typeof(OrderB), order => HandleOrder((OrderB) order) },
    { typeof(OrderC), order => HandleOrder((OrderC) order) },
    { typeof(OrderD), order => HandleOrder((OrderD) order) },
};

Then just fetch the relevant delegate and call it:

orderHandlers[order.GetType()](order);

people

See more on this question at Stackoverflow