5

私はこのコードを持っています:

public async static Task<T?> RequestValue1<T>(Command requestCommand)
                    where T : struct 
{
    // Whatever
}

public async static Task<T> RequestValue2<T>(Command requestCommand)
                    where T : class 
{
    // Whatever
}

2つのメソッドに同じ名前を付けたいです。これも可能ですか?

私の問題:

  • Nullable<T>ifが値型でありifTのインスタンスが参照型である戻り型(要求が失敗した場合はnull、要求が成功した場合は値)のために、2つの異なるメソッドを作成する必要があります。TT
  • asyncref / outを許可しないため、タイプのメソッド引数TTないと推論されず、2つのメソッドに同じ名前を付けることはできません(推論されない場合、ジェネリック制約は署名の競合解決に機能しないため、署名の競合T

現在、このコードは機能しますが、「RequestValue1」と「RequestValue2」の間のこの奇妙な関数呼び出しは好きではありません。

4

3 に答える 3

3

独自のOption型を作成し、それを使用して値が返されるかどうかを示すことができます。

public async static Task<Option<T>> RequestValue<T>(Command requestCommand) {
  ...
}

更新: 型の意図はs とsOption<T>を置き換えることですが、それでもそれらを使用したい場合は、これらの拡張メソッドを使用してギャップを埋めることができます。nullNullable<T>

public static class OptionExtensions {
  public static T? GetNullableValue<T>(this Option<T> option) where T : struct {
    return option.HasValue ? (T?)option.Value : null;
  }
  public static T GetValueOrNull<T>(this Option<T> option) where T : class {
    return option.HasValue ? option.Value : null;
  }
}
于 2012-12-19T14:53:35.937 に答える
1

制約を削除して、呼び出し元がNullable<T>メソッドに型を渡すようにすることができます (つまり、RequestValue<int?>(cmd)の代わりに呼び出しますRequestValue<int>(cmd))。次のように、実行時に null 可能性を確保できます。

public async static Task<T> RequestValue<T>(object arg) {
    var t = typeof (T);
    if (!t.IsClass && (!t.IsGenericType || t.GetGenericTypeDefinition() != typeof(Nullable<>))) {
        throw new ArgumentException("T");
    }
    // Whatever
}
于 2012-12-19T15:01:40.177 に答える
0

次のようなメソッド シグネチャを持つことができます。

    static void test1<T>(Nullable<T> param) where T:struct;
    static void test1<T>(T param) where T:class;

紛争なし。null 非許容の構造体型を渡そうとすると失敗しますが、コンパイラは、null 許容型またはクラス型のパラメーターを指定してオーバーロードを問題なく選択します。

特定のタイプのパラメーターを渡していないため、シナリオは少し異なります。タイプ自体を渡そうとしているだけです。Nullable<T>型の実パラメータがないと、コンパイラは a が他のメソッドよりも 1 つのメソッドに適していると判断できません。私の傾向は、成功または失敗を示すために結果の無効性以外の何らかの手段を使用する方法を提供することです. 通常のTryパターンは次のようになります。

static bool RequestValue1<T>(Command requestCommand, out Task<T> Result);

Result共変であることや型推論に参加することは不可能なので、私はそのパターンが特に好きではありません。別の方法は次のとおりです。

static Task<T> RequestValue1<T>(Command requestCommand, out bool Success);

このような形式では、共分散の問題はありません。別の形式は次のようになります。

static Task<T> RequestValue1<T>(Command requestCommand, out ResultStatus Status);

Succeededここで、ResultStatus は、成功した場合に戻るメソッドを持つ型になりますTrueが、失敗した場合に何が問題なのかを説明する他のメンバーを持つことができます。物事が機能するときに使用するシングルトン インスタンスを定義する不変の抽象型であるSuccess場合、将来的に拡張されて、機能するときに GC プレッシャーを引き起こすことなく、機能しないときに任意のレベルの詳細を提供できます。

残念ながら、outパラメーターの型が依存しないフォームでさえ、T一部のコンテキストでは使用できません。それを可能にするために、概念的に似た方法で成功インジケータとCommandResult<T>組み合わせた構造体型を定義できますが、そのパラメータ型に煩わしい制約はありません。成功インジケータは、または上記のステータス インジケータのいずれかです。TNullable<T>structbool

于 2012-12-19T16:29:38.927 に答える