我正在尝试创建一个有点像这样的通用 xna 物理模块:
class PhysicsModule<T> : where T : Vector2, Vector3
{
private List<PhysicsForce<T>> _globalForces;
public PhysicsModule()
{
_globalForces = new List<PhysicsForce<T>>();
}
/// <summary>
/// Updates the resultant which will be sent to be applied on all entities.
/// </summary>
/// <param name="gameTime">...</param>
public override void UpdateResultant(GameTime gameTime)
{
_resultant = T.Zero;
foreach (PhysicsForce<T> force in _globalForces)
{
T vector = T.Multiply(force.Direction, force.Magnitude);
T modifiedByTime = T.Multiply(vector, (float)gameTime.ElapsedGameTime.TotalSeconds);
_resultant = T.Add(_resultant, modifiedByTime);
}
}
}
class PhysicsForce<T> where T : Vector2, Vector3
{
public T Direction;
public float Magnitude;
}
我知道这段代码行不通,它只是作为一个示例来阐明我想要做什么。 这是可能的还是我会更好地拥有这样的抽象基础
class PhysicsModule2D : PhysicsModule
class PhysicsForce2D : PhysicsForce
最佳答案
- 您需要始终满足所有通用约束
- .net 泛型只允许您从泛型约束调用方法,即取消链接它们不能按名称工作的 C++ 模板。这样做的一个结果是您不能在 T 上使用静态方法或运算符。
- 有一个使用动态类型的解决方法(使用 C# 4 中的
dynamic
关键字或像 MiscUtil 那样动态生成委托(delegate))。但是,这会显着降低性能。 - 有一个丑陋的 hack 可以实现高性能,但它有点复杂。
- 您可以编写带有一些占位符的代码,然后使用代码生成器生成其他版本
- 您可以简单地手动分别实现 2D 和 3D。可能是最佳选择,即使它违反了 DRY。
对于 4),您首先创建一个通用接口(interface),其中包含您要使用的 VectorX 上的所有方法。像这样:
interface VectorMath
{
T Add(T v1,T v2);
}
然后使用struct
实现它。然后将该结构作为第二个通用参数传递给您的类。
关于c# - 使用 Vector2 和 Vector2 作为通用约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5354905/