首页 > 解决方案 > 我可以让相同的方法在浮点数和/或 Vector2 上运行其逻辑吗?

问题描述

我有一个类,其方法采用两个值,一个当前值和一个目标值。该方法使用这些进行大量数学计算并返回与传入的相同类型的值。它还更新类上相同类型的一些属性。

但是,现在我有这个方法的两个副本(以及由它更新的类上的每个属性),一个用于浮点数,一个用于 Vector2,将来我可能需要更多。但是,逻辑是完全相同的(操作是相同的、基本的,并且不关心类型)。

有没有办法让这个类不关心传递给它的方法/具有什么类型的值作为它的属性,只要它是一个浮点数或 Vector2?我尝试了通用路线,但似乎您只能比较泛型而不能相加或相乘等。

我可以有两个不同的类,但我又不想在两个地方有方程。

public float Response { get { return 0.2f; } }
public float Damping { get { return 0.5f; } }
public Vector2 VectorVelocity { get; set; }
public float FloatVelocity { get; set; }

public Vector2 Move(Vector2 current, Vector2 target) 
{   
    Vector2 delta;
    delta = target - current;
    this.VectorVelocity += delta * this.Response;

    current += this.VectorVelocity;
    this.VectorVelocity *= this.Damping;

    return current;
}

public float Move(float current, float target) 
{   
    float delta;
    delta = target - current;
    this.FloatVelocity += delta * this.Response;

    current += this.FloatVelocity;
    this.FloatVelocity *= this.Damping;

    return current;
}

标签: c#.net

解决方案


这是一种通用方法,要求您为各种操作传递委托。

public T Move<T>(T current, T target, 
    Func<T, T, T> subtract, 
    Func<T, T, T> add,
    Func<T, float, T> multiplyByFloat,
    Action<T> setVelocity,
    Func<T> getVelocity,
    ) 
{   
    T delta = subtract(target, current);
    setVelocity(add(getVelocity(), multiplyByFloat(delta, this.Response));    
    current = add(current, getVelocity());
    setVelocity(multiplyByFloat(getVelocity(), this.Damping);    
    return current;
}

然后像这样称呼它

var result = Move(current, target, 
    (a,b) => a - b, 
    (a,b) => a + b,
    (a,b) => a * b,
    v => this.FloatVelocity = v,
    () => this.FloatVelocity);

您可以采用这种方法将论坛保留在一个地方,并且仍然有替代方案来为您发出特定的调用,因为每次都必须让所有这些代表都参与进来会很痛苦。

我还想声明,对于给出的示例,我不确定这是否值得,但如果公式要复杂得多,并且您需要处理 3 种或更多类型,那么这种方法可能没问题,但是如您所见,恕我直言,以这种方式阅读公式要困难得多。


推荐阅读