Search code examples
c#genericsasynchronousnullablemethod-signature

Generics, Nullable, Type inference and function signature conflict


I've this code :

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
}

I want to have the same name for my two methods. Is this even possible ?

My problems:

  • I have to write two different methods because of the return type (I want it to be null if the request failed or a value if the request succeed) which is Nullable<T> if T is a value type, and an instance of T if T is a reference type.
  • async doesn't allow ref/out, so without a method argument of type T, T isn't inferred and my two methods cannot have the same name (signature conflict, as generic constraints doesn't works for signature conflict resolution if T isn't inferred)

Currently this code works but I don't like this strange function calls between "RequestValue1" and "RequestValue2".


Solution

  • You could create your own Option type and use that to indicate if a value is returned or not:

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

    Update: the intent of the Option<T> type is to replace nulls and Nullable<T>s, but if you'd still like to use them, you can use these extension methods to bridge the gap:

    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;
      }
    }