Reputation: 35
I am trying to write generic method, which should parse JToken
to concrete type, by using implicit conversion operator.
I've got my implicit operator like this:
public static implicit operator CategoryDto(JToken token)
{
var result = new CategoryDto
{
//Mapping here
};
And method with generic type:
public static T ParseResult<T>(this JToken response, string relationship) where T : class, new()
{
//Implicit operator is triggered, fields were mapped as expected
CategoryDto concreteResult = response["value"];
//Line below doesn't trigger my custom conversion, even when T is CategoryDto
T result = response["value"];
return result;
}
I would expect my result
variable will be mapped according to implicit operator - but nothing happens, even if I pass CategoryDto
as a T
parameter - T
is CategoryDto
with default values.
I can not understand why this snippet doesn't work (probably due to lack of knowledge about polymorphism/generic types).
Is it related with compile/runtime behavior for generic types?
Upvotes: 0
Views: 909
Reputation: 143078
Compiler will not allow to compile this because this is not type-safe - T
can be any type which matches the constraints and there is no way to guarantee that explicit conversion from T
exists (pre-.NET 7 at least).
Usually you will want to rely on the actual json parsing (possibly using some custom converter), for example:
public static T ParseResult<T>(this JToken response, string relationship) where T : class, new()
=> response["value"].ToObject<T>();
If you really want to leverage the implicit conversion (though I would recommend against it) you can do something like:
public static T ParseResult<T>(JToken response, string relationship) where T : class, new()
{
if (typeof(T) == typeof(CategoryDto))
return (T)(object)(CategoryDto)response["value"];
return response["value"].ToObject<T>();
}
Since .NET 7 you can use static abstract interface members:
public interface IImplicitlyConvertableFromJToken<T> where T : IImplicitlyConvertableFromJToken<T>
{
static abstract implicit operator T(JToken token);
}
class CategoryDto : IImplicitlyConvertableFromJToken<CategoryDto>
{
public static implicit operator CategoryDto(JToken token)
{
var result = new CategoryDto
{
//Mapping here
};
return result;
}
}
public static T ParseResult<T>(JToken response, string relationship)
where T : class, IImplicitlyConvertableFromJToken<T>, new()
=> response["value"];
But again - I strongly recommend to look into using standard parsing from json approaches.
Upvotes: 2