MonTom
MonTom

Reputation: 35

Implicit conversion operator with generic type

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

Answers (1)

Guru Stron
Guru Stron

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

Related Questions