8

次のクラスがあるとします。

public class GenericClass<T>
{
    public T Find()
    {
        //return T if found otherwise null or Nullable<T>
    }
}

Tどこかで を使用してクラスを特殊化したい場合は、 を使用することclassもありstructます。私はこの問題に直面しています:タイプが a に制限されていないNullable<T>場合、 a を返すことはできません。Tstruct

が aまたは の両方で特殊化されFindている場合に機能するメソッドの実装を提供したいと思います。失敗した場合は、それ以外の場合はクラスを返したいと思います。TclassstructFindnullTNullable<T>

リフレクションを使用せずにそれは可能ですか?はいの場合、どのように?

4

3 に答える 3

16

戻ることができdefault(T)ます。

クラスの場合、これはになりますnull。いずれの場合もNullable<T>、これはNullable<T>値なしになります(事実上null)。

そうは言っても、これをタイプとしてではstructなくaで使用すると、構造体のデフォルト値になります。Nullable<T>default(T)


これを任意のクラスまたは構造体で均一に機能させたい場合は、2つの値を返す必要があります。ここでインスピレーションとしてフレームワークを使用し、TryXXXメソッドを使用できます。

public bool TryFind(out T)

default(T)次に、値が見つからない場合に使用して、falseを返すことができます。これにより、null許容型が不要になります。Tuple<bool, T>outパラメータを避けたい場合は、aまたは同様のものを返すようにこれを書くこともできます。

public Tuple<bool, T> Find()

最後のオプションは、潜在的に、クラスを非ジェネリックにしてから、ジェネリックメソッドのペアを使用することです。

class YourClass // Non generic
{
    public T FindReference<T>() where T : class
    {
         // ...
        return null;
    }

    public Nullable<T> FindValue<T>() where T : struct
    {
         // ...
         return default(T);
    }
}

純粋に戻り型に基づいてオーバーロードされたメソッドを持つことはできないため、個別の名前が必要であることに注意してください。

于 2012-10-30T16:29:49.033 に答える
2

私は次の解決策を使用します:

public Boolean Find(out T result)
{
    // Pseudo code
    if (FindItem == true)
    {
        result = ItemFound;
        return true;
    }
    result = default(T);
    return false;
}

なんで?Nullable<T>構造体のみを受け入れ、上記のメソッドはクラスと構造体の両方をサポートするためです。

于 2012-10-30T16:31:15.157 に答える
0

リードが言ったように、あなたは戻ることができますdefault(T)

私の意見では、これには 1 つの大きな欠点があります。アイテムが見つからなかった場合に返されるとメソッドが述べているdefault(T)場合、値の型のデフォルト値を返すことができなくなります (たとえば、通常、返さ0れるFind<int>値は完全に有効な戻り値である可能性があります)。

私はむしろこのようなものに行きたいです

public class GenericClass<T>
{
    public Option<T> Find()
    {
        //return Option.Some(item) if found otherwise Option.None<T>()
    }
}

public static class Option
{
    public static Option<T> None<T>()
    {
        return new Option<T>(default(T), false);
    }

    public static Option<T> Some<T>(T value)
    {
        return new Option<T>(value, true);
    }
}

public sealed class Option<T>
{
    private readonly T m_Value;
    private readonly bool m_HasValue;

    public void Option(T value, bool hasValue)
    {
        m_Value = value;
        m_HasValue = hasValue;
    }

    public bool HasValue 
    {
        get { return m_HasValue; }
    }        

    public T Value 
    {
        get { return m_Value; }
    }
}
于 2012-10-30T16:45:08.730 に答える