0

I am trying to write an anonymous method for the purpose of deserializing Json to a DataContract. This would allow me to have something re-usable without having to write the same code for each DataContract class I wrote for each json query.

The code I have so far, is as follows :

public T Json2Object<T>(string json, Encoding encoding) {
    T result;
    DataContractJsonSerializer ser = new DataContractJsonSerializer( typeof( T ) );
    using ( Stream s = new MemoryStream( ( encoding ?? Encoding.UTF8 ).GetBytes( json ?? "" ) ) ) {
        result = ser.ReadObject( s ) as T;
    }
    return result;
}

It is giving me errors in the IDE as follows :

error

How can this be adjusted without hard-coding the type so that it works as I intend ?

dbc
  • 104,963
  • 20
  • 228
  • 340
Kraang Prime
  • 9,981
  • 10
  • 58
  • 124

1 Answers1

1

The as keyword implies that the type is a reference type, and not a value type. You cannot store null in a value type. Thus, you either need to restrict the type T to a reference type:

public T Json2Object<T>(string json, Encoding encoding) where T : class {
    // ...
}

Or cast rather than use as:

public T Json2Object<T>(string json, Encoding encoding) {
    T result;
    DataContractJsonSerializer ser = new DataContractJsonSerializer( typeof( T ) );
    using ( Stream s = new MemoryStream( ( encoding ?? Encoding.UTF8 ).GetBytes( json ?? "" ) ) ) {
        result = (T)ser.ReadObject( s );
    }
    return result;
}
Rob
  • 26,989
  • 16
  • 82
  • 98
  • Very nice, thank you. Where you have `where T : class` do I need to replace `class` with the specific class. For example, if my datacontract class is named `Foo` would this be written as `where T : Foo` or would that `where T : class` still work as you have it written ? – Kraang Prime Dec 29 '16 at 04:34
  • 1
    @KraangPrime Nope, `where T : class` is exactly what you need to write. It restricts `T` to a *reference type*. Note that you will be forbidden from writing `Json2Object(someJson, someEncoding)` since `int` is a value type. If you want to be able to pass in `int`, you'll need to use the casting approach instead. – Rob Dec 29 '16 at 04:35
  • 1
    That is awesome. Exactly what I needed. Thank you :) – Kraang Prime Dec 29 '16 at 04:36