C# 处理泛型

C# 处理泛型,c#,.net,generics,visual-studio-2008,.net-3.5,C#,.net,Generics,Visual Studio 2008,.net 3.5,我如何能有一个方法,将返回的订单对象动态强制转换为任何特定的订单对象: class Order { ... } class OrderA : Order { ... } class OrderB : Order { ... } class OrderC : Order { ... } class OrderD : Order { ... } private Order GetOrder() { ... } 我做错了什么?试试这个 HandleOrder(OrderA o) { ..

我如何能有一个方法,将返回的订单对象动态强制转换为任何特定的订单对象:

class Order { ... }

class OrderA : Order { ... }

class OrderB : Order { ... }

class OrderC : Order { ... }

class OrderD : Order { ... }


private Order GetOrder() { ... }
我做错了什么?

试试这个

HandleOrder(OrderA o) { ... }
HandleOrder(OrderB o) { ... }
HandleOrder(OrderC o) { ... }
HandleOrder(OrderD o) { ... }
private T GetSpecificOrder(T order)
{
return(T)Convert.ChangeType(T,typeof(T));
}

泛型不能这样做:进入尖括号的类型必须是编译时已知的类型,因此这一行

private T GetSpecificOrder<T>(T order)
    {
     return (T)Convert.ChangeType(T, typeof(T));
    }
以下是如何实施#2:


您需要调用GetSpecificOrder作为所需的派生类:

dynamic myOrder = GetOrder();
HandleOrder(myOrder); // Will dispatch based on the runtime type
var specificOrder=GetSpecificOrder(myOrder);
或投下它:

var specificOrder = GetSpecificOrder<OrderA>(myOrder);
var specificOrder=(OrderA)GetSpecificOrder(myOrder);

然后,您可以为给定的派生类指定任何唯一的属性。

听起来您希望在执行时出现重载解析。那不会发生。。。除非您使用
动态
,否则这可能是最简单的解决方案:

var specificOrder = (OrderA)GetSpecificOrder<Order>(myOrder);
另一种选择是使用,但我个人觉得有点笨重

另一种选择是制作一个
字典
,如下所示:

var myOrder = GetOrder();
var specificOrder = GetSpecificOrder<Order>(myOrder);
HandleOrder(specificOrder);
dynamic order = GetOrder(orderId);
HandleOrder(order); // The right overload will be picked at execution time

如果从
GetOrder
返回的订单类型不正确,则不能将其强制转换为A或B。您必须实际进行映射并实例化正确的类型。如果类型不匹配,则不能向上强制转换。我使用的是.NET 3.5和Visual Studio 2008,所以我想动态是不可能的,对吧?@Héldegonçalves对,
dymamic
直到4.0才可用。但是访问者是语言中立的。是否可以这样做:bool result=orderHandlers[order.GetType()](order)@HélderGonçalves:当然,只要将其从
Action
更改为
Func即可。(您的问题没有显示任何关于方法的返回类型…)非常像(我以前也有类似的问题)
var specificOrder = GetSpecificOrder<OrderA>(myOrder);
var specificOrder = (OrderA)GetSpecificOrder<Order>(myOrder);
dynamic order = GetOrder(orderId);
HandleOrder(order); // The right overload will be picked at execution time
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) },
};
orderHandlers[order.GetType()](order);