0

I've got an uninstantiated generic type, e.g.

public class Dto<T> {
    public T t; 
}

I need to get a JsonContract for this type from DefaultContractResolver. When calling ResolveContract, I've got an ArgumentException - the contract resolver is trying to create a default constructor for this type, which I suspect is illegal for an uninstantiated generic type.

How can I get the contract for this type?

dbc
  • 104,963
  • 20
  • 228
  • 340
Puppy
  • 144,682
  • 38
  • 256
  • 465
  • 1) Can you please include a [complete example](https://stackoverflow.com/help/mcve) of how you are calling `ResolveContract()` when it throws an exception? 2) What do you mean by *uninstantiated generic type*? Do you mean an [open generic type](https://stackoverflow.com/questions/1735035/generics-open-and-closed-constructed-types)? – dbc Mar 18 '16 at 16:50
  • Yes, that is an open generic type. I'll see if I can throw up an ideone or something. – Puppy Mar 18 '16 at 16:52
  • You cannot get a contract for an open generic type. It cannot be serialized or instantiated. Instead each closed type will have its own contract. But I feel this might be an [xy problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Can you explain what you are trying to accomplish? – dbc Mar 18 '16 at 16:53
  • This is not a type. It's just a template. To get a real type out of it you need to know the specific T. – Adrian Zanescu Mar 18 '16 at 16:54
  • I don't want a real type out of it. Nor do I want to serialize or instantiate it. I want a contract describing the template. – Puppy Mar 18 '16 at 16:55
  • @AZ - There are no templates in c#, only generics. And there is a type `typeof(Dto<>)`. If I do `var contract = resolver.ResolveContract(typeof(Dto<>))` if will throw an exception. – dbc Mar 18 '16 at 16:56
  • @Puppy - c# doesn't really have templates, it has generics. See https://msdn.microsoft.com/en-us/library/c6cyy67b.aspx or http://stackoverflow.com/questions/740969/c-sharp-generics-vs-c-templates-need-a-clarification-about-constraints. So I cannot really think what "a contract describing the template" means in this context. If you just want the property names get a contract for `Dto` and go from there. – dbc Mar 18 '16 at 16:59
  • I need their types as well. If I instantiate the DTO with random types, I can't tell teh difference between a real type and the substitute type. I'd also need to somehow make substitute types that match the constraints given on the DTO type, for example. – Puppy Mar 18 '16 at 17:00
  • 1
    @dbc - semantics. i meant template in the casual sense not specific to C# terminology. And if you're trying to say that it is indeed a type - well yes, but if we go this route not all types are equal :) and that's what i was trying to describe with my comment – Adrian Zanescu Mar 18 '16 at 17:01
  • Sure you can. The .NET type system has generic parameter proxy types that stand in for generic parameters; and the generic properties have those types. This is what I used prior to using the JsonContract mechanism. – Puppy Mar 18 '16 at 17:05
  • @Puppy - well you're right - `typeof(Dto<>).GetFields()[0].FieldType` actually returns something. But it's not something instantiable or serializable, so something like [`JsonProperty.DefaultValue`](http://www.newtonsoft.com/json/help/html/Properties_T_Newtonsoft_Json_Serialization_JsonProperty.htm) has no meaning for it. Anyway, since an open generic type cannot be instantiated, it appears `DefaultContractResolver` has no way to give a contract for it. It could certainly fail more gracefully though rather than throwing an exception trying to generate the constructor. – dbc Mar 18 '16 at 17:28
  • It could simply give back a contract describing the properties and then throw if you try to perform some of the operations that you can't perform. – Puppy Mar 18 '16 at 17:30

1 Answers1

0

I ended up dynamically generating a class to stand in for the generic arguments, instantiated it with that, and got the contract for the result. Then when I inspect the contract, I see the placeholder and I know to interpret that myself as referring to the generic parameter.

Puppy
  • 144,682
  • 38
  • 256
  • 465