2016-04-25 4 views
1

T targetValueが「おおよそ」の一部をT currentValueにするのを非同期に待つために使用される静的クラスを作成しています。私はすでに、以下のように正確な等価性をチェックする機能を実装しているが、私は私が作成していた方法は、のようなプリミティブ型を持つ唯一の仕事に意図されている「近似値」ジェネリック型(T:struct)に数式を実行できるかどうかを判断しますか?

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などです。これは、Tstructに強制してジェネリック型をプリミティブに限定する方法を記述するthis SO anwserを実装することで行います。

上記の関数は、私が常に同等であるかどうかを判断するためにstructEqualsを等価と考えることができるので、私の状況でうまくいくように見えます。おおよそ等しいバージョンを作成するときの私の問題は、のようなタイプのTのタイプです。

私は、2つの値が「ほぼ等しい」とき(現在の値がターゲットのx%以内であればtrueを返す)を指定するために関数に「近い」パーセンテージを渡すことを許可します。 Tが数値の場合、私は数学でこれを簡単に行うことができますが、数値以外の場合はこのメソッドを使用するのは意味がありませんが、単にEqualsを使用するだけです。

私はそれのに必要な数学を行うことができるかどうTwhere 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を参照することができますどのようになりますか?

私はこれがかなり可能であるとは思わないか、またはジェネリックメソッドのための良い方法だと思います。だから私が現在言うことから、私の唯一の良い解決策は、私が使用しようとしているそれぞれのタイプ(ベストプラクティス)のために、またはにあるのTypeを確認することです。私は数学をやってそこから行くことができることを知っている(ジェネリックのための悪い習慣)。

おそらく誰かが提案できるより簡単で洗練されたソリューションがありますか?

+0

Tが数値型かどうかを判断するには、http://stackoverflow.com/questions/1749966/c-sharp-how-to-determine-whether-a-type-is-a-numberのようなソリューションを使用します。 – Adrian

答えて

1

悲しいことに、C#でこれを行う方法はありません。

しかし、Jon SkeetとMarc Gravellは、加算、減算、乗算、値の除算などの操作を実行できるgeneric operator frameworkをまとめました。

関連する問題