6

異種コレクション用の型指定されたルックアップ ヘルパー関数が必要です。構造体またはクラスを返す必要があります。アイテムが見つからない場合は null を返す必要があります。以下は、簡単なコレクション ルックアップを使用した例ですが、データベース呼び出しなどである可能性があります。

単一のメソッド署名でこれを達成する方法はありますか?

    public T GetClass<T>(string key)  where T : class
    {
        object o;
        if (Contents.TryGetValue(key, out o))
        {
            return o as T;
        }
        return null;
    }

    public T? GetStruct<T>(string key) where T : struct
    {
        object o;
        if (Contents.TryGetValue(key, out o))
        {
            if (o is T)
            {
                return (T?) o;
            }
        }
        return null;
    }

私がすでに試したこと:

  • オーバーロードを明確にするために一般的な制限を使用できないことを理解しています。したがって、単純にこれら 2 つのメソッドに同じ名前を付けることはできません。
  • 0 は有効な int 値であるため、返す(Default) Tことはできません。
  • タイプとしてを呼び出してみ<int ?>ましたが、説明したようにNullable<T>参照タイプではありません。

ボックス化された int を返すことを示す方法はありますか?

4

3 に答える 3

6

単一のメソッド署名でこれを達成する方法はありますか?

どちらの場合も呼び出しコードが同じに見えるように、オプションのパラメーターを使用してそれを行う恐ろしい (本当に恐ろしい) 方法がありますむずかしいけど。

オプション:

  • Tuple<T, bool>nullity を使用する代わりにa を返す
  • outパラメータを使用する(int.TryParseなど)
  • 異なるメソッド名を使用する

値が存在しないことを個別に通知することによりnull、有効な「見つかった」結果を作成できることに注意してください。これは、場合によっては役立ちます。または、返されないことを保証したい場合もあります

本当に無効を使用したい場合は、最後のオプションを選択します。とにかく、コードがより明確になると思います。IMO、オーバーロードは、メソッドが異なるパラメーターを使用して表現されたまったくNullable<T>同じことを行う場合にのみ使用する必要があります-一方、ある場合Tは戻り値の型として戻り、他の場合は戻り値の型として返すことは、実際にはそのようには見えません。

于 2012-05-02T19:31:30.380 に答える
3

次のメソッドは、クラスと null 許容構造の両方で機能します。

public static T GetValue<T>(string key)
{
    object o;
    if (Contents.TryGetValue(key, out o))
    {
        if (o is T)
        {
            return (T)o;
        }
    }
    return default(T);
}

使用法:

int?   result1 = GetValue<int?>("someInt");
string result2 = GetValue<string>("someString");

?がジェネリック型引数の一部であり、戻り値の型のメソッドによって定義されていないことに注意してください。

于 2012-05-02T19:32:00.310 に答える
1

これは、必要なことを正確に行う必要があります。要求された型が null 許容型である場合は、キャストする前に基になる型を確認してください。

public static T GetValue<T>(string key)
{
    object o;
    if (Contents.TryGetValue(key, out o))
    {
        if (o is T || Nullable.GetUnderlyingType(typeof(T)) == o.GetType())
        {
            return (T)o;
        }
    }

    return default(T);
}

私のテストコード:

Contents.Add("a string", "string value");
Contents.Add("an integer", 1);
Contents.Add("a nullable integer", new Nullable<int>(2));

// Get objects as the type we originally used.
Debug.WriteLine(string.Format("GetValue<string>(\"a string\") = {0}", GetValue<string>("a string")));
Debug.WriteLine(string.Format("GetValue<int>(\"an integer\") = {0}", GetValue<int>("an integer")));
Debug.WriteLine(string.Format("GetValue<int?>(\"a nullable integer\") = {0}", GetValue<int?>("a nullable integer")));

// Get objects as base class object.
Debug.WriteLine(string.Format("GetValue<object>(\"a string\") = {0}", GetValue<object>("a string")));
Debug.WriteLine(string.Format("GetValue<object>(\"an integer\") = {0}", GetValue<object>("an integer")));
Debug.WriteLine(string.Format("GetValue<object>(\"a nullable integer\") = {0}", GetValue<object>("a nullable integer")));

// Get the ints as the other type.
Debug.WriteLine(string.Format("GetValue<int?>(\"an integer\") = {0}", GetValue<int?>("an integer")));
Debug.WriteLine(string.Format("GetValue<int>(\"a nullable integer\") = {0}", GetValue<int>("a nullable integer")));

// Attempt to get as a struct that it's not, should return default value.
Debug.WriteLine(string.Format("GetValue<double>(\"a string\") = {0}", GetValue<double>("a string")));

// Attempt to get as a nullable struct that it's not, or as a class that it's not, should return null.
Debug.WriteLine(string.Format("GetValue<double?>(\"a string\") = {0}", GetValue<double?>("a string")));
Debug.WriteLine(string.Format("GetValue<StringBuilder>(\"a string\") = {0}", GetValue<StringBuilder>("a string")));

結果:

GetValue<string>("a string") = string value
GetValue<int>("an integer") = 1
GetValue<int?>("a nullable integer") = 2

GetValue<object>("a string") = string value
GetValue<object>("an integer") = 1
GetValue<object>("a nullable integer") = 2

GetValue<int?>("an integer") = 1
GetValue<int>("a nullable integer") = 2

GetValue<double>("a string") = 0

GetValue<double?>("a string") = 
GetValue<StringBuilder>("a string") = 
于 2012-05-02T21:18:29.923 に答える