C# Implicit operator with generic

2020-07-17 04:59发布

问题:

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?

回答1:

You can't use implicit for Generic Types.



回答2:

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 best is probably 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;
        }
    }
}