2

汎用関数 Math.Abs​​() を作成したいのですが、これを作成する方法がわかりません。クラスMathを作成すると、Tの型がわからないため、T値のメソッドAbsを作成できません。

誰かがこれを行う方法を知っていれば?

ありがとう

4

4 に答える 4

10

6 つのオプション:

  • の実行時のタイプに基づいてリフレクションを使用するT
  • 気になる型ごとにオーバーロードを使用する
  • 気になるすべてのタイプに if/else を使用する
  • Dictionary<Type, Func<object, object>>関心のあるすべてのタイプのデリゲートを含むを作成します
  • dynamic.NET 4 で使用:

    public T Foo<T>(T value)
    {
        dynamic d = value;
        return Math.Abs(d);
    }
    
  • MiscUtilのMarc Gravell の汎用演算子のようなものを使用します

可能であれば、おそらく過負荷オプションを選択します。コンパイル時に適切に制約し、時間のかかる可能性のあるボクシング/リフレクションを回避します。

于 2012-08-05T18:00:21.083 に答える
4

ジェネリックではこれを行うことはできません-渡された型が数値型であることを保証するジェネリック型の制約はありません。

于 2012-08-05T17:55:25.793 に答える
2

本質的に動作が異なるものに対してジェネリックメソッドを書くのは、単に非論理的だと思います。float と double は同様に機能しますが、int はそのようには機能しません (小数部分がありません)。

各メソッドのオーバーロードを記述することは、これを処理する正しい方法である必要があります。そうしないと、基本的に間違っている if typeof の束を実行することになります。

于 2012-08-05T17:56:27.730 に答える
2

T.GetType() で T の型を取得できます。しかし、それはあなたを助けません。ジェネリック メソッドを作成することはできませんが、オブジェクトの Abs メソッドを作成することはできます。

private static object Abs(object num)
{
    var type = num.GetType();
    if (type == typeof(Int32))
    {
        return Math.Abs((int) num);
    }
    if (type == typeof(Int64))
        return Math.Abs((long)num);
    if (type == typeof(Int16))
        return Math.Abs((short)num);
    if (type == typeof(float))
        return Math.Abs((float)num);
    if (type == typeof(double))
        return Math.Abs((double)num);
    if (type == typeof(decimal))
        return Math.Abs((decimal)num);
    throw new ArgumentException(string.Format("Abs is not defined for type {0}", type.FullName));
}
于 2012-08-05T18:03:50.437 に答える