0

I am trying to create a custom type converter for AutoMapper and my issue is "Cannot implicitly convert type"

This is my converter code:

public class StatusConverter<TValue> : ITypeConverter<string, Wrapper<TValue>> where TValue : Status
{
    public Wrapper<TValue> Convert(string source, Wrapper<TValue> destination, ResolutionContext context)
    {
        return Status.Create(source);
    }
}

The error happens on line return Status.Create(source);, it says can't convert from Wrapper<Status> to Wrapper<TValue>.

I have uploaded all other classes related to this here: https://dotnetfiddle.net/iSr94S

But my question is: Why am I getting this error? I have put a constraint in the method where TValue : Status, so TValue will be of type Status, why is it complaining about the type?

Thanks

Axajkamkat
  • 149
  • 1
  • 6
  • In short because `Wrapper` is not `Wrapper`. [Covariance and Contravariance in C#](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/) can be a useful start for investigation. – Guru Stron Nov 11 '21 at 18:02
  • @GuruStron Could you explain what I have to look in exactly? I tried doing the following as well: `public class StatusConverter : ITypeConverter> where TValue : Enumeration where TType : struct, IComparable { public Wrapper Convert(string source, Wrapper destination, ResolutionContext context) { return Status.Create(source); } }` but I got the same result. – Axajkamkat Nov 11 '21 at 18:11
  • Do you have classes which inherit from `Status` ? What does `Wrapper` actually do? – Guru Stron Nov 11 '21 at 18:17
  • @GuruStron No, I do not. The idea is that my `Enumeration` class is the base class. All classes inheriting from it will be `sealed`. In this case `Status` will be sealed, but for demo purposes I didn't do it here. `Wrapper` will be have information such as whether the creation failed, succeeded, if failed why, and the `Value`. I simplified it in my demo only with a `Value`. – Axajkamkat Nov 11 '21 at 18:18
  • 1
    If you don't then `where TValue : Status` does not make any sense. change your code to `StatusConverter: ITypeConverter>` – Guru Stron Nov 11 '21 at 18:19
  • I see, that helps solve the problem, thank you. One additional question, is it possible to make the generic here be `Enumeration` and make it work with all classes inheriting from it (without reflection, preferably, or is it a must in this case?)? – Axajkamkat Nov 11 '21 at 18:22
  • TBH right now without real code I would not help a lot. Maybe there is an x-y problem here. – Guru Stron Nov 11 '21 at 19:34

1 Answers1

0

As I said in comments reason for such behavior is that classes in C# does not support variance, i.e. Wrapper<SomeStatusChild> is not Wrapper<Status> (explained here, for example). If you don't have Status inheritors you can just do:

public class StatusConverter : ITypeConverter<string, Wrapper<Status>>
{
    public Wrapper<Status> Convert(string source, Wrapper<Status> destination, ResolutionContext context)
    {
        return Status.Create(source);
    }
}
Guru Stron
  • 102,774
  • 10
  • 95
  • 132