Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Implicit operator with generic

I'm writing an abstract wrapper for enum in C # (I want something like enum in Vala). My code is:

    public abstract class Wraper<T, TE>
        where T : Wraper<T, TE>, new()
    {
        public TE Value;

        public static implicit operator T(TE value)
        {
            return new T() { Value = value };
        }

        public static implicit operator TE(T value)
        {
            return value.Value;
        }
    }

I want to do with something like this:

    public enum EFoo { A, B, C, D, E};
    public class Foo : Wraper<Foo, EFoo>
    {
        public bool IsBla
        {
            get { return Value == EFoo.A || Value == EFoo.E; }
        }
    }

    ...

    Foo foo = EFoo.A;
    bool bla = foo.IsBla;

But the code does not compile because C # does not allow both generic parameter,. When compile reports an error:

User-defined conversion must convert to or from the enclosing type

On line

public static implicit operator T(TE value)

Is there any work around or in C# is not so simple?

like image 933
Murdej Ukrutný Avatar asked Sep 11 '15 08:09

Murdej Ukrutný


1 Answers

The implicit operator must convert either from or to the class you are defining it in. Since you are trying to define it in the abstract base class, it can only convert from or to that class.

The line Foo foo = EFoo.A; does not work because you can't define that conversion in your abstract class, you can only define it in your Foo class.

If you changed your code, as I did below, to convert from/to the base class, the implicit conversions work but you don't get the result you want. Wraper<Foo,EFoo> foo2 = EFoo.A; works because it can be defined in the base class.

Your best bet is probably to use the initializer syntax when creating your foo Foo foo = new Foo { Value = EFoo.A }; or to create some generic conversion functions.

public abstract class Wraper<T, TE>
    where T : Wraper<T, TE>, new()
{
    public TE Value;
        
    public static implicit operator TE(Wraper<T, TE> value)
    {
        return value.Value;
    }

    public static implicit operator Wraper<T, TE>(TE value)
    {
        return new T { Value = value };
    }
}

public enum EFoo
{
    A,
    B,
    C,
    D,
    E
}

public class Foo : Wraper<Foo, EFoo>
{
    public bool IsBla
    {
        get
        {
            return Value == EFoo.A || Value == EFoo.E;
        }
    }
}
like image 83
Grax32 Avatar answered Oct 10 '22 23:10

Grax32