One can have method signatures like:
static void test1<T>(Nullable<T> param) where T:struct;
static void test1<T>(T param) where T:class;
without conflict. Attempting to pass a non-nullable struct type will fail, but the compiler will have no problem selecting an overload given a parameter of either a nullable type or a class type.
Your scenario is a little different, since you aren't passing a parameter of a particular type; you're just trying to pass the type itself. Without an actual parameter of the type, the compiler won't be able to decide that a Nullable<T>
is a better fit for one method than the other. My inclination would be to offer a method which uses some other means than the nullity of the result to indicate success or failure. The normal Try
pattern would look like:
static bool RequestValue1<T>(Command requestCommand, out Task<T> Result);
I don't especially like that pattern, since it's impossible for Result
to be covariant or participate in type inference. An alternative would be:
static Task<T> RequestValue1<T>(Command requestCommand, out bool Success);
Such a form would have no problem with covariance. An alternative form would be something like:
static Task<T> RequestValue1<T>(Command requestCommand, out ResultStatus Status);
where ResultStatus would be a type with a Succeeded
method that returns True
in case of success, but could have other members that explain what's wrong in case of failure. If it's an immutable abstract type which defines a singleton Success
instance for use when things work, it could be extended in future to provide an arbitrary level of detail when things don't work without causing any GC pressure when they do.
Unfortunately, even the forms where the out
parameter type doesn't depend upon T
can't be used in some contexts. To allow for that, one could define a struct type CommandResult<T>
which combines a T
with a success indicator, in a fashion conceptually similar to Nullable<T>
but without annoying struct
constraint on its parameter type. The success indicator could either be a bool
, or could be a status indicator as described above.