2009-07-02 11 views
10

¿Es posible convertir una clase personalizada en un tipo de valor?C#: conversión personalizada a un tipo de valor

He aquí un ejemplo:

var x = new Foo(); 
var y = (int) x; //Does not compile 

¿Es posible hacer que lo anterior suceda? ¿Debo sobrecargar algo en Foo?

+0

¿Qué esperas que haga? I.o.w, ¿cómo se ve Foo? –

Respuesta

23

Tendrá que sobrecargar el operador de reparto.

public class Foo 
    { 
     public Foo(double d) 
     { 
      this.X = d; 
     } 

     public double X 
     { 
      get; 
      private set; 
     } 


     public static implicit operator Foo(double d) 
     { 
      return new Foo (d); 
     } 

     public static explicit operator double(Foo f) 
     { 
      return f.X; 
     } 

    } 
+0

¿Puede explicar el uso de implícita y explícita en su respuesta? Gracias. –

+0

Plz ver MSDN: http://msdn.microsoft.com/en-us/library/xhbhezf4(VS.80).aspx http://msdn.microsoft.com/en-us/library/z5z9kes2(VS .71) .aspx (Yo preferiría siempre los operadores explícitos de cast) –

+1

Excelente, exactamente lo que buscaba en la respuesta. Aclamaciones. –

6

Crear una conversión explícita o implícita:

public class Foo 
{ 
    public static explicit operator int(Foo instance) 
    { 
     return 0; 
    } 

    public static implicit operator double(Foo instance) 
    { 
     return 0; 
    } 
} 

La diferencia está, con las conversiones explícitas que tendrá que hacer el tipo Arrójate:

int i = (int) new Foo(); 

y con conversiones implícitas, solo puede "asignar" cosas:

double d = new Foo(); 

MSDN tiene esto que decir:

"Al eliminar conversiones innecesarias, las conversiones implícitas pueden mejorar la legibilidad del código fuente. Sin embargo, dado que las conversiones implícitas no requieren que los programadores emitan explícitamente de un tipo a otro, se debe tener cuidado para evitar resultados inesperados. En general, los operadores de conversión implícitos nunca deben arrojar excepciones y nunca perder información para que puedan usarse de forma segura sin la conciencia del programador. Si un operador de conversión no puede cumplir esos criterios, debe marcarse explícitamente. "(El énfasis es mío)

0

Otra posibilidad es escribir un método de extensión analizar y TryParse para su clase

A continuación, iba a escribir el código de la siguiente manera:.

var x = new Foo(); 
var y = int.Parse(x); 
+2

¿por qué lo escribirías como un método de extensión, y no como un método de miembro regular? Es su clase, por lo que tiene control sobre ella. –

+2

Porque cuando tienes un martillo, cada problema es un clavo. –

+1

@Mark: incluso si escribiste un método de extensión, no podrías usarlo con "var y = int.Parse (x);" porque los métodos de extensión solo se aplican a las instancias. Tendría que hacer algo como "var y = x.ParseToInt();" en su lugar, y en ese caso, ¿por qué no simplemente poner el método ParseToInt en la clase misma, como dice Frederik? – LukeH

5

Es necesario definir explicit o implicit de calidad:

public class Foo 
{ 
    public static implicit operator int(Foo d) 
    { 
     return d.SomeIntProperty; 
    } 

    // ... 
Cuestiones relacionadas