【问题标题】:Structure of Arrays in C# - reducing boilerplate code writingC# 中的数组结构 - 减少样板代码编写
【发布时间】:2017-07-17 15:25:45
【问题描述】:

我正在用 C# 编写游戏,我正在使用 SoA 模式来处理性能关键的组件。

这是一个例子:

public class ComponentData
{
    public int[] Ints;
    public float[] Floats;
}

理想情况下,我希望其他程序员只指定这些数据(如上)并完成它。但是,必须对每个数组进行一些操作,例如分配、复制、增长等。现在我正在使用带有抽象方法的抽象类来实现这些操作,如下所示:

public class ComponentData : BaseData
{
    public int[] Ints;
    public float[] Floats;

    protected override void Allocate(int size)
    {
        Ints = new int[size];
        Floats = new float[size];
    }

    protected override void Copy(int source, int destination)
    {
        Ints[destination] = Ints[source];
        Floats[destination] = Floats[source];
    }

    // And so on...
}

这要求程序员在每次编写新组件和添加新数组时添加所有这些样板代码。

我尝试通过使用模板来解决这个问题,虽然这适用于 AoS 模式,但它对 SoA 并没有多大好处(Data : BaseData<int, float> 会非常模糊)。

所以我想听听关于在某处自动“注入”这些数组以减少大量样板代码的想法。

【问题讨论】:

    标签: c# templates data-oriented-design


    【解决方案1】:

    想法如下:

    public abstract class ComponentData : BaseData
    {
        public Collection<Array> ArraysRegister { get; private set; }
    
        public int[] Ints;
    
        public float[] Floats;
    
        public ComponentData()
        {
          ArraysRegister = new Collection<Array>();
          ArraysRegister.Add(this.Ints);
          ArraysRegister.Add(this.Floats);
          /* whatever you need in base class*/
        }
    
        protected void Copy(int source, int destination)
        {
          for (int i = 0; i < ArraysRegister.Count; i++)
          {
            ArraysRegister[i][destination] = ArraysRegister[i][source];
          }
        }
        /* All the other methods */
    }
    
    public class SomeComponentData : ComponentData
    {
        // In child class you only have to define property...
        public decimal[] Decimals;
    
        public SomeComponentData()
        {
          // ... and add it to Register
          ArraysRegister.Add(this.Decimals);
        }
        // And no need to modify all the base methods
    }
    

    然而它并不完美(必须通过分配来完成),但至少实现子类您不必重写处理数组的基类的所有方法。是否值得做取决于你有多少类似的方法。

    【讨论】:

    • 我明白了。这真的很好!将解决复制粘贴所有内容的大部分痛苦。谢谢!
    • 乐于助人)
    【解决方案2】:

    我建议定义类使用的所有数组的集合,然后循环对所有数组进行所有必要的操作。

    【讨论】:

    • 不确定我是否关注。不是至少要写同样多的代码吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2018-12-05
    • 1970-01-01
    相关资源
    最近更新 更多