Niharika Verma
Niharika Verma

Reputation: 83

C# : how to accept two generic parameters

I have a function which I want to convert the below Ping and Pong to generic type. Is it possible?

private Pong ReadDataFromApi(string url, Ping data)
{
    string url = "URL_TO_HIT";

    WebResponse response = Util.SendWebRequest<Ping>(url, data, 30000);

    var res = new Pong();
    if (response != null)
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            var objText = reader.ReadToEnd();
            res = JsonConvert.DeserializeObject<Pong>(objText);
        }
    }
    return res;
}

I could convert to something below :

private T ReadDataFromApi(string url, T data)  T : class
{
    string url = "URL_TO_HIT";

    WebResponse response = Util.SendWebRequest<T>(url, data, 30000);

    var res = new Pong();
    if (response != null)
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            var objText = reader.ReadToEnd();
            res = JsonConvert.DeserializeObject<Pong>(objText);
        }
    }
    return res;
}

Not sure how to accept the Pong as a generic parameter.

Upvotes: 4

Views: 181

Answers (5)

isxaker
isxaker

Reputation: 9446

void foo<TOne, TTwo>() 
   where TOne : BaseOne
   where TTwo : BaseTwo

var fooObj = foo<Ping,Pong>(url, data);

see MSDN

Upvotes: 0

Kahbazi
Kahbazi

Reputation: 14995

you can use it like this

private TPong ReadDataFromApi<TPing,TPong>(string url, TPing data) 
        where TPing : class 
        where TPong : class, new()

Upvotes: 1

Ren&#233; Vogt
Ren&#233; Vogt

Reputation: 43876

Change your method to that:

private TPong ReadDataFromApi<TPong, TPing>(string url, TPing data)  TPong : class, new() where TPing : class
{
    string url = "URL_TO_HIT";
    WebResponse response = Util.SendWebRequest<TPing>(url, data, 30000);

    var res = new TPong(); // USE TPong HERE
    if (response != null)
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            var objText = reader.ReadToEnd();
            res = JsonConvert.DeserializeObject<TPong>(objText); // AND HERE
        }
    }
    return res;
}

With the new() constraint you ensure that the TPong has a default constructor. You need this to be able to do res = new TPong();

And pass the generic parameter TPong to DeserializeObject<TPong>.

Upvotes: 1

Matt Burland
Matt Burland

Reputation: 45135

Your signature should be something like:

private T ReadDataFromApi<S,T>(string url, S data) where S : class where T : class

Then calling it equivalent to your original function would be something like:

var myPong = ReadDataFromApi<Ping,Pong>(url, data);

Your signature would be kind of similar to the one for Func<T, TResult> for example

Upvotes: 0

Yacoub Massad
Yacoub Massad

Reputation: 27861

Something like this should work:

private TPong ReadDataFromApi<TPing, TPong>(string url, TPing data)
    where TPing : class
    where TPong : class,new() //You need to create instances of TPong
{
    WebResponse response = Util.SendWebRequest<TPing>(url, data, 30000);

    var res = new TPong(); //Create instance of TPong
    if (response != null)
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            var objText = reader.ReadToEnd();
            res = JsonConvert.DeserializeObject<TPong>(objText);
        }
    }

    return res;
}

Upvotes: 7

Related Questions