Home > Software engineering >  Return a generic type of another generic type
Return a generic type of another generic type

Time:11-13

I have a custom Enum class:

public abstract class Enum<T> where T : struct, IComparable
{
    public T Id { get; }

    public string Value { get; }
    
    protected Enum(T id, string @value)
    {
        Id = id;
        Value = @value;
    }
}

And another class which inherits from this class:

public sealed class Status : Enum<byte>
{
    public static readonly Status Pending = new Status(0, "PENDING");
    public static readonly Status Finished = new Status(1, "FINISHED");
    
    private Status(byte id, string name) : base(id, name)
    {
    }
    
    public static Status Create (string @value)
    {
        // some logic here
        //return Wrapper.Wrap(Finished);
        return Finished;
    }
    
    public static Wrapper<Status> CreateWrapper(string @value)
    {
        // some logic here
        return Wrapper.Wrap(Finished);
    }
}

Now I want to make a custom type converter in AutoMapper and these following converters work fine:

public class StatusConverter<TType> : ITypeConverter<string, Enum<byte>>
{
    public Enum<byte> Convert(string source, Enum<byte> destination, ResolutionContext context)
    {
        return Status.Create(source);
    }
}

public class StatusConverter2<TValue> : ITypeConverter<string, Wrapper<Status>> // works fine
{
    public Wrapper<Status> Convert(string source, Wrapper<Status> destination, ResolutionContext context)
    {
        return Status.CreateWrapper(source);
    }
}

Now I created a new Wrapper class:

public class Wrapper
{
    public static Wrapper<T> Wrap<T>(T @value)
    {
        return new Wrapper<T>(@value);
    }
}

public class Wrapper<T>
{
    T Value;
    
    internal Wrapper(T @value)
    {
        Value = @value;
    }
}

And I want to do the following:

public class StatusConverter3<TValue> : ITypeConverter<string, Wrapper<Enum<byte>>> // doesn't work with Enum<T>
{
    public Wrapper<Enum<byte>> Convert(string source, Wrapper<Enum<byte>> destination, ResolutionContext context)
    {
        return Status.CreateWrapper(source);
    }
}

I want to create a generic type converter, but I get an error that I cannot implicitly convert from Wrapper<Status> to Wrapper<Enum<byte>>.

Here is a dotnetfiddle demo of my problem: https://dotnetfiddle.net/xM9JVg

CodePudding user response:

You should use Covariant generic modifier

  1. Introduce an interface

    public interface IWrapper<out T> 
    { 
    }
    
  2. Implement it on your Wrapper

    Wrapper<T> : IWrapper<T>
    
  3. Use the interface in your converters instead of a class

    public class StatusConverter3<TValue> : ITypeConverter<string, IWrapper<Enum<byte>>> 
    

Be aware that in this case your Wrapper<T> wouldn't be allowed to have a methods that took T as input parameters

Check the fork

  • Related