Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从给定参数类型推断所需类类型的通用系统_C#_Generics - Fatal编程技术网

C# 从给定参数类型推断所需类类型的通用系统

C# 从给定参数类型推断所需类类型的通用系统,c#,generics,C#,Generics,我在游戏中有一个基本的“订单”架构——每个订单都有一个基本的数据类型和一个“订单处理器”,它根据给定的数据执行一些操作。例如“移到这一点” 我希望有一个整洁的系统,在这个系统中,我可以简单地传递顺序数据,并且正确的顺序处理器将启动,这样我就可以轻松地添加新的OrderData/OrderProcessor类,而无需修改其他类,也无需乱用枚举或强制转换,所以看起来泛型是一个不错的选择 这是我目前的代码。对于如何在“OrderService”类中正确的“OrderProcessor”和“IOrder

我在游戏中有一个基本的“订单”架构——每个订单都有一个基本的数据类型和一个“订单处理器”,它根据给定的数据执行一些操作。例如“移到这一点”

我希望有一个整洁的系统,在这个系统中,我可以简单地传递顺序数据,并且正确的顺序处理器将启动,这样我就可以轻松地添加新的OrderData/OrderProcessor类,而无需修改其他类,也无需乱用枚举或强制转换,所以看起来泛型是一个不错的选择

这是我目前的代码。对于如何在“OrderService”类中正确的“OrderProcessor”和“IOrderData”对之间绘制连接,我没有给出答案。有关更多信息,请参见
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类型,我明白了。在这种情况下,没有办法实现这一点,因为泛型是编译时特性,而实际类型是在运行时提供的。您可能会使用非通用的基本接口。