Oliver Dixon
Oliver Dixon

Reputation: 7405

Null OR generic as parameter method

In Java you can do this:

protected void makeRequest<T extends BaseJsonClass, T2 extends BaseJsonClass> (Response<T> response, T2 dataToSend, String url) {}

Some request:

makeRequest(response, null, serverUrl);
makeRequest(response, jsonData, serverUrl);

In C# how?

I'm writing a method that should be able to accept data as null or as a specific type of object.

/**
 * Make a request to the server.
 * dataToSend can be null.
 * */
protected void makeRequest<T, T2>(Response<T> response, T2 dataToSend, string url) where T : JsonObjectBase where T2 : JsonObjectBase
{ }

Currently I'm getting the problem:

The type arguments for method `BaseModelController.makeRequest<T,T2>(Response<T>, T2, string)'
cannot be inferred from the usage. Try specifying the type arguments explicitly

How would I allow a generic that can possibly be null as well?

** EDIT 1 ** I invoke this method like so:
makeRequest(response, null, serverUrl);
or
makeRequest(response, someJsonData, serverUrl);

** EDIT 2 **

JsonObjectBase is just an object that is extended by other Json classes so I can parse/serialize them auto-magically knowing that it will always be a Json object. I use it for type checking so other coders don't make the mistake of entering an unknown object.
Passing null is really much better than defining the same value which is 'suppose' to not do anything; because that gets messy very fast.

Example of the power

ModelControllerAccount.getInstance().createUser(
            username.text, password.text, // Params
            new Response<JsonUserAccountFeedback>(
                success: (jsonObjectStandardResponse) => Debug.Log("Success when creating account. Data: " + jsonObjectStandardResponse.getAccessToken()),
                failed: (failedReason) => Debug.Log("Failed to make request. Reason: " + failedReason.getReasonDescription())
            )
        );

Upvotes: 1

Views: 192

Answers (3)

Julian A
Julian A

Reputation: 344

Since you're most likely only need access to the methods of JsonObjectBase you could do something like this:

    protected void MakeRequest<T>(Response<T> response, JsonObjectBase dataToSend, string url) where T : JsonObjectBase
    {    
    }

and call the method like this: MakeRequest(response, null, serverUrl);

Or you could even take advantage of optional arguments:

    protected void MakeRequest<T>(Response<T> response, string url, JsonObjectBase dataToSend = null) where T : JsonObjectBase
    {
    }

and call the method like this: MakeRequest(response, serverUrl);

Upvotes: 1

Justin Grant
Justin Grant

Reputation: 46663

If you can change the API somewhat, one easy way to fix this would be to add an overload that omits the second parameter. This is easier for the caller too in cases where you're not sending any data.

Like this:

protected void makeRequest<T>(Response<T> response, string url) where T : JsonObjectBase 
{ 
    makeRequest (response, default(JsonObjectBase), url); 
}

Upvotes: 3

Ben N
Ben N

Reputation: 2923

This happens because a value of null doesn't tell the compiler the type of that parameter. After all, the implementation of makeRequest could check the type of T2 and do wildly different things depending on what it sees. If you had passed, say, a variable with the type of List<int>, it would know that T2 is List<int>, but null could be the value of any reference type. If the compiler can't figure out the type (or if it ever decides the wrong one), you'll need to tell it:

Response<string> myResponse;
makeRequest<Response<string>, object>(myResponse, null, "http://example.com");

I've just specified the types used to call the generic method. In this case, the type of the null parameter is object.

Upvotes: 0

Related Questions