2011-05-10 11 views
12

Estoy tratando de ser flojo e implementar los operadores de conversión en la clase base abstracta en lugar de en cada una de las clases concretas derivadas. He logrado lanzar de una manera, pero no puedo lanzar la otra. Creo que tal vez no sea posible, pero quería recoger el colectivo SO mente antes de renunciar:implementando un operador de conversión en una clase abstracta genérica

public interface IValueType<T> 
{ 
    T Value{ get; set; } 
} 

public abstract class ValueType<T> : IValueType<T> { 
    public abstract T Value { get; set; } 
    public static explicit operator T(ValueType<T> vt) { 
     if(vt == null) 
      return default(T); 
     return vt.Value; 
    } 

    public static implicit operator ValueType<T>(T val) { 
     ValueType<T> vt = new ValueType<T>(); //<--- obviously this won't work as its abstract 
     vt.Value = val; 
     return vt; 
    } 
} 
+0

parte de mí piensa que podría hacer esto con la reflexión, pero la mayor parte de mi dice que tiene más sentido hacerlo en las clases derivadas, porque es el trabajo de la clase derivada individual saber cómo pasar de T a él, no el trabajo de t él clase abstracta. –

+0

En realidad, no creo que puedas hacerlo incluso con reflexión, ya que son métodos estáticos, y lo que estaba pensando requería métodos de instancia. –

+0

@Matt Ellen Estoy de acuerdo en que es mejor hacerlo en las clases concretas, pero prefiero escribir el método una vez en lugar de copiarlo en docenas de clases derivadas. –

Respuesta

10

Usted necesidad de introducir otro parámetro genérico para identificar el tipo de hormigón.

algo así ..

public interface IValueType<T> 
{  
    T Value{ get; set; } 
} 

public abstract class ValueType<T,K> : 
    IValueType<T> where K : ValueType<T,K>,new() 
{  
    public abstract T Value { get; set; }  
    public static explicit operator T(ValueType<T,K> vt) 
    {   
     if(vt == null)    
      return default(T);   
     return vt.Value;  
    }  

    public static implicit operator ValueType<T,K>(T val) 
    {   
     K k = new K(); 
     k.Value = val; 
     return k;  
    } 
} 

Cree su clase concreta

public class Test : ValueType<int,Test> 
{ 
    public override int Value {get;set;} 
} 

Entonces

var t = new Test(); 
t.Value = 99; 
int i = (int)t; 
Test t2 = (Test)6; 

Console.WriteLine(i); 
Console.WriteLine(t2); 
+0

Veo que todavía tiene que lanzar explícitamente un 'int' a' Test': 'Test t2 = (Test) 6;'. Supongo que es porque no podemos implementar el operador implícito estático público K (T val) {...} 'sin incurrir en un error en tiempo de compilación (CS0556). –

+0

Pensé en una solución de encadenar a los operadores implícitos pero me quedé atrapado allí, ver: http://stackoverflow.com/questions/6001854/chaining-implicit-operators-in-generic-c-classes –

Cuestiones relacionadas