2009-05-06 26 views
16

Además de la cuestionable utilidad de esto, me gustaría preguntar si es posible hacer algo en esta línea.Primitivas personalizadas en C#?

class MyPrimitive { 
     String value; 
     public String Value { 
      get { return value; } 
      set { this.value = value; } 
     } 
} 

// Instead of doing this... 
MyPrimitive a = new MyPrimitive(); 
a.Value = "test"; 
String b = a.Value; 

// Isn't there a way to do something like this? 
MyPrimitive a = "test"; 
String b = a; 

me gusta para envolver los tipos primitivos en clases personalizadas mediante una propiedad para realizar el método get y set realizar otras cosas, como la validación.
Como hago esto con frecuencia, pensé que sería bueno tener también una sintaxis más simple, como para las primitivas estándar.
Aún así, sospecho que esto no solo no es factible sino que también podría ser un error conceptual. Cualquier idea sería muy bienvenida, gracias.

Respuesta

29

Utilice un tipo de valor (struct) y asígnele un implicit conversion operator del tipo que desee en el lado derecho de la asignación.

struct MyPrimitive 
{ 
    private readonly string value; 

    public MyPrimitive(string value) 
    { 
     this.value = value; 
    } 

    public string Value { get { return value; } } 

    public static implicit operator MyPrimitive(string s) 
    { 
     return new MyPrimitive(s); 
    } 

    public static implicit operator string(MyPrimitive p) 
    { 
     return p.Value; 
    } 
} 

EDIT: Hecho la estructura inmutable porque Marc Gravell tiene toda la razón.

+0

Esto es exactamente lo que busca el asker. No es exactamente una "primitiva personalizada", pero imita una tan bien como sea posible, y es la forma correcta de hacerlo en C#. – Noldorin

+4

Si lo convierte en una estructura, debe ** completamente ** hacerlo inmutable al mismo tiempo; tener un {get; set;} en una estructura es una muy, muy mala idea. ¿Mencioné la maldad? –

+0

Totalmente de acuerdo, disculpe la confusión. Originalmente, equivocadamente, traté de imitar su ejemplo lo más fielmente posible. –

1

Puede usar fundición implícita. No se recomienda, pero:

public static implicit operator string(MyString a) { 
    return a.Value; 
} 
public static implicit operator MyString(string a) { 
    return new MyString { value = a; } 
} 

De nuevo, mala práctica.

+1

No estoy seguro de que invariablemente sea una "mala práctica". Depende del contexto, en mi opinión. – Noldorin

+0

El uso de operadores de conversión en tipos de referencia oculta la creación de instancias de objetos nuevos; o peor, devuelve una referencia antigua que para los tipos mutables (no la cadena) solo puede causar problemas. Para mí, es preferible solo para los operadores de conversión en los tipos de valor, y deje los tipos de referencia para subir y bajar. –