2015-09-11 13 views
0

Я пишу абстрактную оболочку для перечисления в C# (я хочу что-то вроде перечисления в Вала). Мой код:C# Неявный оператор с общим

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; 
     } 
    } 

Я хочу сделать что-то вроде этого:

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; 

Но код не компилируется, потому что C# не позволяет как общий параметр ,. При компиляции выдает сообщение об ошибке:

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

На линии

public static implicit operator T(TE value) 

Есть ли работа вокруг или в C# не так просто?

+1

возможно дубликат [ошибки оператора явного преобразования при преобразовании общих списков] (http://stackoverflow.com/questions/1971925/explicit-conversion-operator-error-when-converting-generic-lists) – dotctor

+1

It не имеет ничего общего с общими параметрами - проблема в том, что C# допускает только операторы преобразования от или к типу, где они определены, - в этом случае ни 'T', ни TE не являются этим типом, насколько компилятор может сказать , Вам действительно нужны эти неявные преобразования? Что делать, если вы просто указали поля enum values ​​типа wrapping (это в значительной степени реализовано как перечисление Java)? – Luaan

+0

Можете ли вы не использовать 'public static implicit operator Wrapper (значение TE)'? –

ответ

-2

Вы не можете использовать неявные для общих типов.

1

Неявный оператор должен преобразовать либо из класса, либо в класс, в котором вы его определяете. Поскольку вы пытаетесь определить его в абстрактном базовом классе, он может преобразовывать только из или в этот класс.

Строка Foo foo = EFoo.A; не работает, потому что вы не можете определить это преобразование в своем абстрактном классе, вы можете определить его только в своем классе Foo.

Если вы изменили свой код, как я сделал ниже, для преобразования из/в базовый класс, неявные преобразования работают, но вы не получите желаемого результата. Wraper<Foo,EFoo> foo2 = EFoo.A; работает, потому что он может быть определен в базовом классе.

Лучше всего, вероятно, использовать синтаксис инициализатора при создании вашего foo Foo foo = new Foo { Value = EFoo.A }; или создать некоторые общие функции преобразования.

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; 
     } 
    } 
}