简体   繁体   中英

Can I return null value for one of the items in a Tuple?

I have a method which returns two values (HttpResponse and Generic object). Below is the code snippet.

In some condition I have to return one of the items as null. I tried the following condition but it didn't work.

internal sealed class OnlineHelper<T>
{
   internal static Tuple<T, HttpStatusCode> GetRequest(arg1, arg2...)
   {
      ....
      if (webResponse.StatusCode == HttpStatusCode.OK)
      {
          return Tuple.Create(serializer.Deserialize<T>(response),
                     webResponse.StatusCode);
      }


      return Tuple.Create(null, webResponse.StatusCode); // Compiler error
      return Tuple.Create(default(T), webResponse.StatusCode);
      // ^- Throwing null reference exception.

   }
}

Yes, you can. If you do this it works:

var tuple = Tuple.Create<string, int>(null, 42);

What you tried to was have the compiler determine the type for the null and it can't do that so you have to explicitly provide the generic types.

So, in your case, try this:

return Tuple.Create<T, HttpStatusCode>(null, webResponse.StatusCode);

You would also need to add the generic class constraint to your method to allow null to be cast to T .

internal static Tuple<T, HttpStatusCode> GetRequest(arg1, arg2...)
    where T : class

You can use the simple constructor: new Tuple<T, HttpStatusCode>() or Tuple.Creare . The tricky part here is that you need to cast null to your generic type, so it should allow nulls.

Alter your class declaration to support nulls:

internal sealed class OnlineHelper<T> where T: class

And later cast or use default(T)

return new Tuple<T, HttpStatusCode>((T)null, webResponse.StatusCode)

Your compiler error stems from the fact that you never put a constraint to T . I could instantiate your class with T as int for example and you cannot set an int to null . So setting a T to null in your code must not compile (and it does not).

I don't know where your NRE comes from in your second try. It's absolutely correct.

return new Tuple<T, HttpStatusCode>(null, someErrorCode);

However, that would mean you'd have to constraint T to reference types, by using the class keyword (if you omit this constraint, it could be class or struct , which means it works for both reference and value types):

internal static Tuple<T, HttpStatusCode> GetRequest(arg1, arg2...) where T : class
{

In .NET Core and .NET Framework 4.7 you can use ValueTuple.

public (ApplicationUser, string) CreateUser()
{
   return (null, errMsg);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM