0

I have a class called RootObject:

public class RootObject
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int Address { get; set; }
}

public void getdata()
{
    WebRequest request = WebRequest.Create("http://addresstojson.com/json.json");
    WebResponse response = await request.GetResponseAsync();

    using (var stream = new StreamReader(response.GetResponseStream()))
    {
       json = JsonConvert.DeserializeObject<RootObject>(stream.ReadToEnd());
    }
}

In the last statement of the getdata() method, the type is passed:

JsonConvert.DeserializeObject</*here*/>(Stream.ReadToEnd())

I would like to pass the type as parameter to the getdata(RootObject) method.

Is there a way to do this in C# using generics?

maraaaaaaaa
  • 7,749
  • 2
  • 22
  • 37
Waqas Kanju
  • 94
  • 12
  • 2
    `public void getdata() { ... DeserializeObject(...)` – Ron Beyer Sep 28 '15 at 17:51
  • Generic types are compile-time constant, if you need a generic parameter your method must declare it. – Preston Guillot Sep 28 '15 at 17:52
  • It makes no sense for `getdata` to do this unless you also change it to return a `T` (since `json` would have to be a `T` itself). – crashmstr Sep 28 '15 at 17:54
  • possible duplicate of [What is cool about generics, why use them?](http://stackoverflow.com/questions/77632/what-is-cool-about-generics-why-use-them) – Jeroen Vannevel Sep 28 '15 at 17:54
  • More info: https://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx https://msdn.microsoft.com/en-us/library/512aeb7t.aspx https://msdn.microsoft.com/en-us/library/sz6zd40f.aspx – Jeroen Vannevel Sep 28 '15 at 17:55

2 Answers2

12

The standard way to implement strongly-typed deserialization is this:

public T Get<T>()
{
    string json = ...; // get data somehow
    return JsonConvert.DeserializeObject<T>(json);
}

It looks like you want to read results asynchronously, so you need to actually return the result as Task<T>, as well as to use xxxxAsync versions of methods that read data:

public Task<T> GetData<T>()
{
    WebRequest request = WebRequest.Create("http://addresstojson.com/json.json");
    using (WebResponse response = await request.GetResponseAsync())
    {
        using(var stream = new StreamReader(response.GetResponseStream()))
        {
            string json = await stream.ReadToEndAsync();
            T result = JsonConvert.DeserializeObject<T>();
            return result;
        }
    }
}

You can learn more about generics here: https://msdn.microsoft.com/en-us/library/512aeb7t.aspx

Dmytro Shevchenko
  • 33,431
  • 6
  • 51
  • 67
0
public static async Task<T> GetData<T>(string add)
    {
        WebRequest request = WebRequest.Create(add);
        WebResponse response = await request.GetResponseAsync();

        using (var stream = new StreamReader(response.GetResponseStream()))
        {
            return JsonConvert.DeserializeObject<T>(stream.ReadToEnd());
        }
    }
Waqas Kanju
  • 94
  • 12
  • Could you please clarify why this is different/better than earlier answer? Looks identical to the other answer (with addition of `async` which clearly was not part of original question). – Alexei Levenkov Sep 29 '15 at 05:44
  • Sorry, i forget to write the `async` in the question. When i applied the answer given to me by @Dmytro Shevchenko. It showed me this error.**Can not implicitly convert Type T to RootObject.**. After little change in the answer. It worked. I found the answer in this link. [Answer](http://stackoverflow.com/questions/27406715/pass-class-as-a-parameter-to-method) – Waqas Kanju Sep 29 '15 at 15:31