正在寻找一种方法来更改可变数量的方法参数类型C#

正在寻找一种方法来更改可变数量的方法参数类型C#,c#,C#,在中,实体与组件中的数据保持关系,然后每个组件由多个系统操作。每个系统可以依赖于许多组件 目前,我正在基类中实现这些系统,并在寻找组件并将其耦合到同一个实体方面做了大量繁重的工作。很多这项工作都是使用泛型完成的,而且效果非常好 public abstract class System<T1>: System where T1: Component { public override void Update( long delta ) {

在中,实体与组件中的数据保持关系,然后每个组件由多个系统操作。每个系统可以依赖于许多组件

目前,我正在基类中实现这些系统,并在寻找组件并将其耦合到同一个实体方面做了大量繁重的工作。很多这项工作都是使用泛型完成的,而且效果非常好

public abstract class System<T1>: System
    where T1: Component
{        

    public override void Update( long delta )
    {
        ComponentStorage<Component> componentStorage1 = GetComponentStorageByType<T1>( );

        List<Entity> entities = GetEntities( );

        if ( componentStorage1 == null )
            return;

        entities.ForEach( e =>
        {
            int index = entities.IndexOf( e );

            if ( componentStorage1[ index ] == null )
                return;

            Update( (T1) componentStorage1[ index ], delta );
        } );
    }

    protected abstract void Update( T1 component1, long delta );
}
公共抽象类系统:系统
其中T1:组件
{        
公共覆盖无效更新(长增量)
{
ComponentStorage componentStorage1=GetComponentStorageByType();
List entities=GetEntities();
if(componentStorage1==null)
返回;
entities.ForEach(e=>
{
int index=实体。IndexOf(e);
if(componentStorage1[索引]==null)
返回;
更新((T1)组件存储1[索引],增量);
} );
}
受保护的抽象无效更新(T1组件1,长增量);
}
继承的类重写了名为Update的方法,我通过Update方法从存储中向该方法传递实例化的组件

class TestSystem1: System<TestComponent1>
{
    protected override void Update( TestComponent1 component1, long delta )
    {
        Console.WriteLine( $"{component1.Count++}" );
    }
}
类TestSystem1:系统
{
受保护的覆盖无效更新(TestComponent1 component1,长增量)
{
WriteLine($“{component1.Count++}”);
}
}
这适用于只有一个组件的系统。如果系统有多个组件,我将不得不为多个组件添加另一个通用Tn,这意味着实现不限数量的类

我已经研究了不同数量的泛型参数,但是

我也许可以将反射应用于魔法,但在我用尽所有其他选择之前,我宁愿不要

有没有一种设计能满足我的需要?我想让继承的类保持最完整
-调用覆盖、受保护的更新方法(或类似方法),并将已转换的组件交给它。

一些可能的选项包括:

  • 使用生成一组支持1到16个参数的
    系统
    基类。这是一个编译时解决方案
  • 系统
    只接受一个参数,但如果
    T
    本身不是组件,则将其视为复合组件。在我看来,它的实现和使用都更简单。例如:
所需的类组件
{
组件1第一个{get;set;}
组件2秒{get;set;}
}
类TestSystem:System
{
受保护的覆盖无效更新(组件所需组件,长增量)
{
WriteLine($“{components.First}”);
WriteLine($“{components.Second}”);
}
}

反射可以用来获取组件中的属性类型,这些属性需要一次,然后缓存以在下次加速。

我很喜欢复合的想法,但是你仍然需要在继承的类中解包,这意味着用户实现。T4模板对于解决我的问题非常有用,可以进行代码更改,并希望能够多次复制代码。@mstehula,为什么需要解包?复合材料可以按原样传递。在派生类中使用它与从复合对象获取属性一样简单。我扩展了代码示例以使其更清晰。
系统
基类可以对所有用例实现一次。我猜解包也是指强制转换。无论它是否在复合材料中,我们都不知道您的示例中第一个或第二个的类型。在我的测试用例中,TestSystem依赖于知道它使用哪些组件来允许它访问组件数据,这些数据不是从基类组件继承的@pbalaga@mstehula:仍不需要浇铸。所需的
组件
是为从
系统
派生的类中要操作的每个不同参数集创建的。您知道编写代码时需要使用的确切类型,否则无法在
TestComponent
类中使用它。不同之处在于,在基类
系统中
必须动态获取
T
中定义的属性类型,然后为每个此类类型调用
GetComponentStorageByType(propertyType)
。应该不需要单个显式强制转换。你现在觉得这更清楚了吗?是的。在系统旁边创建组合,在我的例子中,它被称为TestSystem1Components。一切继承的东西都很好,很漂亮,我一直在努力想在基本系统中该怎么做。知道更新方法的类型与以前相同,将泛型类型传递给基础系统。由于反射类型查找,不需要强制转换@帕巴拉加
    class ComponentsRequired
    {
       Component1 First { get; set; }
       Component2 Second { get; set; }
    }

    class TestSystem : System<ComponentsRequired>
    {
        protected override void Update( ComponentsRequired components, long delta )
        {
            Console.WriteLine( $"{components.First}" );
            Console.WriteLine( $"{components.Second}" );
        }
    }