【发布时间】:2016-08-19 03:47:57
【问题描述】:
我正在创建一个静态类,用于异步等待一些T targetValue“近似”为一些T currentValue。我已经实现了一个检查完全相等的函数,如下所示,但是我很难使用“近似值”
public delegate T GetValueMethod<T>() where T: struct;
public static Task<Boolean> WaitForExactValueAsync<T>(GetValueMethod<T> getValue, T targetValue, CancellationToken cancelWaitToken, int msTimeout = 10000) where T: struct
{
return Task.Run<Boolean>(async () =>
{
// Create a CancellationToken that times out, then link it with the argument token that requests a the wait to be cancelled
var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(msTimeout));
var timeoutAndCancelTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutTokenSource.Token, cancelWaitToken);
// Continually check to see if we reached the target value or have timed out
T currentValue = getValue();
while (!targetValue.Equals(currentValue) && !timeoutAndCancelTokenSource.IsCancellationRequested)
{
try { await Task.Delay(500, timeoutAndCancelTokenSource.Token); }catch (Exception ex) { }
currentValue = getValue();
}
// If we got here and the token is not cancelled that means we have reached the target value
return !timeoutAndCancelTokenSource.IsCancellationRequested;
});
}
我正在创建的方法仅适用于原始类型,例如int、double、Boolean 等。我通过实现 this SO anwser 来做到这一点,它描述了一种将泛型类型限制为原始类型的方法通过强制T 成为struct。
上面的函数似乎很适合我的情况,因为(我认为)我们总是可以将struct 等同于Equals 来确定相等性。创建近似相等版本时我的问题是T 的类型类似于Boolean。
我计划允许用户将“接近”百分比传递给函数,以指定两个值何时“近似相等”(如果当前在目标的 x 百分比范围内,则返回 true)。如果T 是一个数值,我可以很容易地用数学来做到这一点,但是当它不是数字时,使用这种方法是没有意义的,而只是使用Equals。
有没有办法告诉T (where T : struct) 我是否可以在上面执行我需要的数学运算(要实现下面的IsValueClose 方法)?
private static Boolean ValueIsClose<T>(T target, T value, double percentAsDecimal)
where T: struct
{
// if(value.CanDoTheMaths)
{
return Math.Abs((value / target) - target) <= percentAsDecimal;
}
// else
{
return target.Equals(value);
}
}
此外,一旦发生这种情况,我如何将 target 和 value 称为可以执行这些数学运算的类型?
在我认为这对于泛型方法不太可能或良好做法之前,从提出一些相关的问题开始。因此,据我目前所知,我唯一的好解决方案是为我计划使用的每种类型制作一个“近似”方法(最佳实践),或者在IsValueClose 中检查T 的Type 以查看如果这是我知道的东西,我可以做数学并从那里开始(泛型的坏做法)。
虽然有人可以建议一个更简单更优雅的解决方案?
【问题讨论】:
-
使用stackoverflow.com/questions/1749966/… 之类的解决方案来确定 T 是否为数字类型。