Casey Crookston
Casey Crookston

Reputation: 13945

Method that returns a nullable, generic type

This is what I'm trying to do:

public T GetByID<T>(BaseAPI api)
{
    ....
    try
    {
        var response = (HttpWebResponse)httpRequest.GetResponse();
        var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

        T returnObject = JsonConvert.DeserializeObject<T>(responseString);
        return returnObject;
    }
    catch (Exception ex)
    {
        return null;
    }
}

The problem is that the return null line throws an error, which I understand, because T is not nullable. So, I'm trying to make T be nullable, and I'm not figuring it out. No matter what I try, I get this:

The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable'

I'm trying various forms of this:

public T? GetByID<T>(BaseAPI api)
{
    ....
    try
    {
        var response = (HttpWebResponse)httpRequest.GetResponse();
        var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

        T? returnObject = JsonConvert.DeserializeObject<T?>(responseString);
        return returnObject;
    }
    catch (Exception ex)
    {
        return null;
    }
}

I've seen a few other threads asking roughly the same question, but none of them have been specific enough to help me get all the way there. This one is REALLY close, but I'm not getting the answer to work for me.

Upvotes: 0

Views: 93

Answers (2)

Boris Modylevsky
Boris Modylevsky

Reputation: 3099

To return null should mark the T as class and return its default value:

public T GetByID<T>(BaseAPI api) where T: class
{
    ....
    try
    {
        var response = (HttpWebResponse)httpRequest.GetResponse();
        var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

        T returnObject = JsonConvert.DeserializeObject<T>(responseString);
        return returnObject;
    }
    catch (Exception ex)
    {
        return default(T);
    }
}

Upvotes: 1

gh9
gh9

Reputation: 10703

You need to set the generic constraint at the class level

public class foo<T> where T : class

public T bar(){returns null;} will now compile

EDIT explaining why it works

When you use generics the compiler doesnt know what type it is. Since there are reference types and non reference types you cannot just return null. Because T needs to work for both reference types and non reference types.

By stating a constraint that T is a class you are stating it is a reference type and thus can return null.

Edit

Per the comments the correct way would be

default(T)

I will copy past the reason why and link to the question

Return default(T) which means you'll return null if T is a reference type (or a nullable value type), 0 for int, '\0' for char etc

original question

Upvotes: 1

Related Questions