【问题标题】:Am I misusing C# generics?我在滥用 C# 泛型吗?
【发布时间】:2014-10-30 15:52:47
【问题描述】:

我倾向于严重依赖泛型,但我担心我会误用它们。

例如,我有一个Entity,其中包含Component 的子类字典,组件的类型是键,组件是值。例如PositionComponentColorComponent 等。

我有分离和获取组件的方法,定义如下:

class Entity
{
    Dictionary<Type, Component> components;

    //...

    void DetachComponent<T>() 
        where T : Component 
    {
        components.Remove(typeof(T));
    }

    T GetComponent<T>()
        where T : Component
    {
        return (T)components[typeof(T)];
    }
}

我正在讨论的替代方案只是让函数使用参数:void DetachComponent(Type componentType),但我不喜欢像这样调用每个方法:entity.DetachComponent(typeof(ColorComponent));

这是对泛型的滥用吗?我通常对容器类这样做,因为使用类型作为键的键值对对我来说很有意义。

【问题讨论】:

  • 这只会允许每种类型的单个组件,不是吗
  • @RowlandShaw 不太清楚你在问什么,我省略了添加组件的代码,因为它在方法中不使用泛型。
  • @Shane 他只是指出,如果您在每种类型的基础上注册/取消注册,那么您不能拥有相同类型的多个实例(否则调用 detach 会随机删除一个,因为您没有任何关于您要删除此类型的“哪个”的信息,因为您只传递了类型)。我很确定这对你来说没问题,但我认为这是他的问题
  • 这看起来像一些单身商店...
  • @RonanThibaudau 这是有道理的。是的,每个实体中只有一种类型的组件。

标签: c# generics dictionary key-value


【解决方案1】:

我看不出有什么问题。

对于 DetachComponent,根本不需要使用泛型 - 将类型作为泛型参数传递,而不是仅传递常规的 (Type componentType) 参数,您将一无所获。

对于 GetComponent,使用泛型允许您在编译时返回正确的类型,而 调用代码 不必强制转换它。在这里,使用泛型是有意义的。

因为使用泛型

  • GetComponent
  • 有意义
  • 不会因为DetachComponent 而受到伤害,

我认为出于一致性的原因,将它用于两者都是有意义的(即,完全按照你所做的那样做)。

【讨论】:

  • 感谢您的回复。我很好奇您是否有更好的存储方法的想法?整个问题假设我使用的是带有键的字典作为类型。我已经使用 Enum 的组件类型实现了,但这让我觉得我只是在划分代码并使其变得更加复杂。
  • @Shane:如果您的实体可以拥有每个组件的 0-1 个实例,我喜欢您的解决方案。您不需要在枚举中重复您的类名,并且您的 T : Component 通用约束可以方便地确保只有组件将传递给您的 Attach/Get/Detach 方法。
猜你喜欢
  • 2011-05-07
  • 2018-04-26
  • 2018-06-14
  • 2015-07-30
  • 1970-01-01
  • 2011-05-31
  • 2016-07-03
  • 2011-04-20
  • 2015-03-29
相关资源
最近更新 更多