0

私はこの機能を持っています:

public static U? IfNotNull<T, U>(this T? self, Func<T, U?> func)
    where T : struct
    where U : struct
{
    return (self.HasValue) ? func(self.Value) : null;
}

例:

int? maybe = 42;
maybe.IfNotNull(n=>2*n); // 84

maybe = null;
maybe.IfNotNull(n=>2*n); // null

明示的な型だけでなく、暗黙的にnull許容の参照型でも機能するようにしたいと思いNullable<>ます。この実装は機能します:

public static U IfNotNull<T, U>(this T? self, Func<T, U> func)
    where T : struct
    where U : class
{
    return (self.HasValue) ? func(self.Value) : null;
}

ただし、もちろん、過負荷解決では型の制約は考慮されないため、両方を同時に持つことはできません。これに対する解決策はありますか?

4

2 に答える 2

8

しかしもちろん、過負荷の解決は型の制約を考慮しません

そうですね...しかし、メソッド自体の型制約ではありません。パラメータタイプのタイプ制約を調べます。

C#4(オプションのパラメーターがあります)では、これを行うことができます...しかし、私は本当にあなたがしないことをお勧めします:

public class MustBeStruct<T> where T : struct {}
public class MustBeClass<T> where T : class {}

public static U? IfNotNull<T, U>(this T? self, Func<T, U?> func,
                       MustBeStruct<U> ignored = default(MustBeStruct<U>))
    where T : struct
    where U : struct
{
    return (self.HasValue) ? func(self.Value) : null;
}

public static U IfNotNull<T, U>(this T? self, Func<T, U> func,
                                MustBeClass<U> ignored = null)
    where T : struct
    where U : class
{
    return (self.HasValue) ? func(self.Value) : null;
}

この恐ろしい、恐ろしいハックの詳細については、このブログ投稿を参照してください。

個人的には、おそらく2つのメソッドの名前を変えて、オーバーロードの解決にそれほど苦労する必要がないようにします。また、コードのリーダーもそうしませんでした。

于 2012-07-09T19:26:55.407 に答える
0

だから私はこれで終わった:

public static U IfNotNull<T, U>(this T self, Func<T, U> func)
    where U : class
{
    return (self != null)
        ? func(self)
        : (U)null;
}

public static U? IfNotNull<T, U>(this T self, Func<T, U?> func)
    where U : struct
{
    return (self != null)
        ? (U?)func(self)
        : null;
}

オーバーロードリゾルバはこれに満足しているようです。Nullable<>これは、タイプの場合は少し余分な作業です。

object o = null;
o.IfNotNull(x => x.ToString());
o.IfNotNull(x => x.GetHashCode() as int?);

int? i = null;
i.IfNotNull(x => Math.Abs(x.Value).ToString());
i.IfNotNull(x => Math.Abs(x.Value) as int?);
于 2012-07-17T19:56:06.943 に答える