【问题标题】:Determine if generic type (where T: struct) has the ability to have maths performed on it? [duplicate]确定泛型类型(其中 T: struct)是否有能力对其进行数学运算? [复制]
【发布时间】: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;
    });
}

我正在创建的方法仅适用于原始类型,例如intdoubleBoolean 等。我通过实现 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);
    }
}

此外,一旦发生这种情况,我如何将 targetvalue 称为可以执行这些数学运算的类型?

在我认为这对于泛型方法不太可能或良好做法之前,从提出一些相关的问题开始。因此,据我目前所知,我唯一的好解决方案是为我计划使用的每种类型制作一个“近似”方法(最佳实践),或者在IsValueClose 中检查TType 以查看如果这是我知道的东西,我可以做数学并从那里开始(泛型的坏做法)。

虽然有人可以建议一个更简单更优雅的解决方案?

【问题讨论】:

标签: c# generics


【解决方案1】:

遗憾的是,在 C# 中没有办法做到这一点。

不过,Jon Skeet 和 Marc Gravell 组合了一个 generic operator framework,允许对值执行加法、减法、乘法和除法等操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 2012-11-28
    • 2011-04-09
    • 1970-01-01
    相关资源
    最近更新 更多