次のコード スニペットのようなものを実現しようとしています。
赤い線が示すように、動作しMath.Min
てIComparable<T>
いないようです。このジェネリック クラスに対してMath.Min
orを使用する必要があります。Math.Max
はT
どちらint
かdouble
またはdecimal
タイプになります。
どうすればこれを簡単に解決できますか?
次のコード スニペットのようなものを実現しようとしています。
赤い線が示すように、動作しMath.Min
てIComparable<T>
いないようです。このジェネリック クラスに対してMath.Min
orを使用する必要があります。Math.Max
はT
どちらint
かdouble
またはdecimal
タイプになります。
どうすればこれを簡単に解決できますか?
独自のジェネリックMax
を作成し、Min
public static T Max<T>(T x, T y)
{
return (Comparer<T>.Default.Compare(x, y) > 0) ? x : y;
}
算術演算の一般的な解決策はありません。ただし、単純な比較のために、自分で簡単に実装できます。
T Min<T>(T x1, T x2) where T:IComparable<T>
{
int comp=x1.CompareTo(x2);
if(comp<=0)
return x1;
else
return x2;
}
IComparable<T>
しかし、私は一般的に制約を避け、ユーザーにIComparer<T>
パラメーターとしてコンストラクターに渡すように依頼し、ユーザーがComparer<T>.Default
指定しない場合はデフォルトにします。
IComparable<T>
この手法により、ユーザーが別の実装を渡せば、を実装しない型でもクラスを使用できます。
class Foo<T>
{
readonly IComparer<T> _comparer;
public Foo()
:this(Comparer<T>.Default)
{
}
public Foo(IComparer<T> comparer)
{
_comparer=comparer;
}
T Min(T x1, T x2)
{
int comp = _comparer.Compare(x1,x2);
if(comp <= 0)
return x1;
else
return x2;
}
}
さて、それはint、decimal、またはdoubleになるので、醜いハックは次のようにすることです
if not null
if(decimal.tryparse(val.ToString(), out aDecimal))
and if the other value can be made into a decimal
return math.max or min or what ever.
私はすでに疑似コードを使用して後悔しています...
含める数値タイプに応じて、上記のチェックに最大のものを使用します。
ただし、誰かが「このクラスはジェネリックです。小数をラップするクラスで使用しましょう」と言うとすぐに、苦痛の世界に陥り、ここに投稿された他のオプションのいくつかを見る時が来ました.