2

I am trying to write a method that will take a generic object and convert it into a type of T. The context is, I've just made a REST API call and I have the content of the response in value. In THIS case, I happen to know that the return type is an array of strings.

enter image description here

But of course, that won't always be the case.

using (var response = await client.SendAsync(request))
{
    HttpContent result = response.Content;
    object value = ((ObjectContent)result).Value;

    List<string> list = GenericToStronglyTyped<List<string>>(value);
    List<string> list2 = GenericToStronglyTyped_v2<List<string>>(value);
}

I found a similar question here that seemed positive: Cast object to T

And I tried the suggested answer as follows:

private T GenericToStronglyTyped<T>(object obj)
{
    if (obj is T)
    {
        return (T)obj;
    }
    try
    {
        return (T)Convert.ChangeType(obj, typeof(T));
    }
    catch (InvalidCastException)
    {
        return default(T);
    }
}

However, this returns null because of:

Object must implement IConvertible.

So I came up with my own solution:

private T GenericToStronglyTyped_v2<T>(object obj)
{            
    try
    {
        string json = JsonConvert.SerializeObject(obj);
        return JsonConvert.DeserializeObject<T>(json);
    }
    catch (InvalidCastException)
    {
        return default(T);
    }
}

That DOES work, but it feels like a bit of a gimmick. What is the best way to go about this?

Thanks!

Casey Crookston
  • 13,016
  • 24
  • 107
  • 193
  • It depends on the type of the object and if the object can actually be converted to the target type – Jonathan Alfaro Dec 11 '19 at 23:33
  • 1
    your string[] is not a list, so you cant cast it to that, you would have to do something like `((string[])value).ToList()`. JsonConvert can handle this, because it looks at the string and tries to parse the values. – Charles Dec 11 '19 at 23:43
  • 1
    but this obviously will not work there is no conversion between `string[]` and `List` ... feel free to use `GenericToStronglyTyped>` or `GenericToStronglyTyped` ... v2 obviously will work as `List` and `T[]` has the same JSON representation – Selvin Dec 11 '19 at 23:44
  • You may also be interested in seeing how how object mappings are accomplished in the Dapper library, which is one of the best-performing: https://github.com/StackExchange/Dapper – brnlmrry Dec 12 '19 at 00:34
  • You might try a few different ways. First try an `as` cast, then check if the type is convertible (using `is IConvertible`), then try a *classic* cast (with a `catch`). Take a look at @ericlippert's answer to https://stackoverflow.com/questions/2139798/does-it-make-sense-to-use-as-instead-of-a-cast-even-if-there-is-no-null-check (and the link on his blog) – Flydog57 Dec 12 '19 at 00:53

1 Answers1

4

That DOES work, but it feels like a bit of a gimmick. What is the best way to go about this?

I feel that you're venturing into opinion here, but, here's mine: the solution you've presented as being gimmicky is both well-tested and extremely easy to read. I'll take those all day long.

If at some point the serialization is too much overhead, then come back and take a closer look. But especially when shunting stringy data around, there are just too many edge cases to consider. This is a solved problem, so I'd recommend appreciating that those libraries exist and moving on to your actual business logic.

brnlmrry
  • 399
  • 2
  • 7