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

时间:2019-03-09 18:13:33

标签: c#

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

当前,我正在基类中实现系统,并进行了大量繁重的工作来查找并将组件耦合到同一实体。许多操作都是使用泛型完成的,并且效果很好。

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 );
}

继承的类重写了称为Update的方法,我将实例化的组件从存储传递给update方法。

class TestSystem1: System<TestComponent1>
{
    protected override void Update( TestComponent1 component1, long delta )
    {
        Console.WriteLine( $"{component1.Count++}" );
    }
}

这仅适用于只有一个组件的系统。如果系统具有多个组件,那么我将不得不为多个组件添加另一个通用Tn,这意味着最多可以实现无限数量的类。

我研究了数量可变的通用参数,C++11 has it C# does not

我也许可以使反射适合魔术,但是直到我用尽所有其他选项之前,我宁愿不这样做。

有没有可以满足我需求的设计?我希望继承的类保持最完整 -调用覆盖的,受保护的Update方法(或类似方法),并将已转换的组件交给它。

1 个答案:

答案 0 :(得分:1)

一些可能的选项是:

  • 使用T4 template生成一组System<>基类,并支持例如1至16个参数。这是一个编译时解决方案。
  • 具有System<T>仅接受一个参数,但是如果T本身不是组件,请将其视为组合。 IMO,它的实现和使用都更加简单。例如:
    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}" );
        }
    }

反射可用于一次获取ComponentsRequired中的属性类型,然后将其缓存以加快下次速度。