C# 从给定参数类型推断所需类类型的通用系统
我在游戏中有一个基本的“订单”架构——每个订单都有一个基本的数据类型和一个“订单处理器”,它根据给定的数据执行一些操作。例如“移到这一点” 我希望有一个整洁的系统,在这个系统中,我可以简单地传递顺序数据,并且正确的顺序处理器将启动,这样我就可以轻松地添加新的OrderData/OrderProcessor类,而无需修改其他类,也无需乱用枚举或强制转换,所以看起来泛型是一个不错的选择 这是我目前的代码。对于如何在“OrderService”类中正确的“OrderProcessor”和“IOrderData”对之间绘制连接,我没有给出答案。有关更多信息,请参见C# 从给定参数类型推断所需类类型的通用系统,c#,generics,C#,Generics,我在游戏中有一个基本的“订单”架构——每个订单都有一个基本的数据类型和一个“订单处理器”,它根据给定的数据执行一些操作。例如“移到这一点” 我希望有一个整洁的系统,在这个系统中,我可以简单地传递顺序数据,并且正确的顺序处理器将启动,这样我就可以轻松地添加新的OrderData/OrderProcessor类,而无需修改其他类,也无需乱用枚举或强制转换,所以看起来泛型是一个不错的选择 这是我目前的代码。对于如何在“OrderService”类中正确的“OrderProcessor”和“IOrder
OrderService
类内部:
public interface IOrderData
{
}
// an order processor reads data from an IOrderData object until the data object says stop
public abstract class OrderProcessor<T> where T : IOrderData
{
protected T m_currentData;
public virtual void Start(T data)
{
m_currentData = data;
}
}
////////////////////////
public class MoveOrderData : IOrderData
{
public Vector3 Destination { get; private set; }
}
public class MoveOrderProcessor : OrderProcessor<MoveOrderData>
{
public override void Start(MoveOrderData data)
{
base.Start(data);
}
}
////////////////////////
public class OrderService<T> where T : IOrderData
{
private Dictionary<System.Type, OrderProcessor<T>> m_processors = new Dictionary<System.Type, OrderProcessor<T>>();
private OrderProcessor<T> m_currentProcessor;
public void GiveOrder(IOrderData data)
{
// this is the main problem: I'm not sure how to say "the given data is type 'MoveOrderData' so find out which
// OrderProcessor class handles those and pass it in". A simple switch statement and cast would suffice here
// but I'd like to automate the process
}
}
公共接口IOrderData
{
}
//订单处理器从IOrderData对象读取数据,直到数据对象显示停止
公共抽象类OrderProcessor,其中T:IOrderData
{
受保护的T m_currentData;
公共虚拟无效开始(T数据)
{
m_currentData=数据;
}
}
////////////////////////
公共类MoveOrderData:IOrderData
{
公共向量3目标{get;private set;}
}
公共类MoveOrderProcessor:OrderProcessor
{
公共覆盖无效开始(MoveOrderData)
{
基本启动(数据);
}
}
////////////////////////
公共类OrderService,其中T:IOrderData
{
专用字典m_处理器=新字典();
专用OrderProcessor m_currentProcessor;
公共命令(IOrderData数据)
{
//这是主要的问题:我不知道如何说“给定的数据是‘MoveOrderData’类型,所以请找出哪种类型
//OrderProcessor类处理这些内容并将其传入”。在这里,一个简单的switch语句和cast就足够了
//但我想让这个过程自动化
}
}
一个可能的解决方案是将
OrderService
类设置为非通用类,因为它可以处理不同类型的订单/订单处理程序(根据注释)。然后维护一个字典
,它包装操作
,从OrderProcessor
调用Start
方法
我对原始代码进行了一些扩展,以展示它是如何工作的
公共接口IOrderData
{
}
公共类MoveOrderData:IOrderData
{
公共向量3目标{get;private set;}
}
公共类AttackOrderData:IOrderData
{
}
公共抽象类OrderProcessor,其中T:IOrderData
{
受保护的T CurrentData{get;set;}
公共虚拟无效开始(T数据)
{
CurrentData=数据;
}
}
公共类MoveOrderProcessor:OrderProcessor
{
}
公共类AttackOrderProcessor:OrderProcessor
{
}
公共类订购服务
{
私有只读字典m_处理器=新字典();
公共秩序服务
{
AddProcessor(新的MoveOrderProcessor());
AddProcessor(新的AttackOrderProcessor());
}
私有void AddProcessor(OrderProcessor processor),其中T:IOrderData
{
var action=(action)processor.Start;
添加(typeof(T),obj=>action((T)obj));
}
公共命令(IOrderData数据)
{
var action=m_处理器[data.GetType()];
动作?调用(数据);
}
}
它会导致向下转换obj=>操作((T)obj)
,但这不应该是问题,因为您的数据被约束到IOrderData
接口。用法示例
var service=neworderservice();
service.GiveOrder(新的MoveOrderData());
service.GiveOrder(新的AttackOrderData());
这里真的需要泛型吗?如果只为订单数据和处理器提供基类呢?您不能让每个订单自己处理处理-为什么您需要一个OrderProcessor来处理特定的订单类型?那么在OrderService中我该怎么说呢“我已收到MoveOrderData类型的对象,请将其传递给MoveOrderProcessor,而不是AttackOrderProcessor、JumpOrderProcessor等?您不能只使用GiveOrder
中的泛型参数:public void GiveOrder(t data)…顺便说一句:OrderProcessor
中的m_CurrentMember
应该是T
@EmmetOT-Ah类型,我明白了。在这种情况下,没有办法实现这一点,因为泛型是编译时特性,而实际类型是在运行时提供的。您可能会使用非通用的基本接口。