2010-04-09 18 views
15

Ok, sé que la sobrecarga de propiedades no es compatible con C# - la mayoría de las referencias lo explican al citar el problema de un solo método-diferente-tipo de retorno. Sin embargo, ¿qué hay de los setters? Me gustaría asignar un valor directamente como una cadena u objeto, pero solo devolver como una cadena.Propiedades de sobrecarga en C#

De esta manera:

public string FieldIdList 
    { 
     get { return fieldIdList.ToString(); } 
     set { fieldIdList = new FieldIdList(value); } 
    } 

    public FieldIdList FieldIdList 
    { 
     set { fieldIdList = value; } 
    } 
    private FieldIdList fieldIdList; 

¿Por qué no se permitirá este? También he visto que las "propiedades" simplemente crean funciones getter/setter en la compilación. ¿Sería posible crear el mío? Algo como:

public void set_FieldIdList(FieldIdList value) 
    { 
     fieldIdList = value; 
    } 

Eso haría lo mismo. ¿Pensamientos?

+1

Fui mordido por el mismo problema, y ​​estoy bastante decepcionado por esta limitación del lenguaje (porque no veo ninguna razón para ello). Por extraño que parezca, las propiedades son la genial característica del lenguaje C# que echo de menos en C++, y allí, me parece que les falta mucho. – paercebal

Respuesta

7

Las propiedades son, de hecho, un par de métodos get/set (uno de los cuales puede omitirse), pero la propiedad en sí tiene metadatos adicionales que la convierten en una propiedad en lugar de solo dos métodos.

Porque la firma de la propiedad sigue siendo no válida según el tipo solo-diferente-por-devolución, incluso si solo tiene un colocador. Si necesita esto, no use una propiedad; las propiedades set-only no son algo bueno de todos modos.

+0

Entonces, el compilador crea una firma para un par de métodos, y eso es lo que evita sobrecargas adicionales? ¿Esto solo hace que las propiedades sean convenientes o hay más que eso? ¿Qué datos adicionales lo convierten en una propiedad? –

+0

No exactamente. Del mismo modo que no puede tener dos variables de un tipo diferente con el mismo nombre, no puede tener dos propiedades con un tipo diferente y el mismo nombre. Los problemas son los mismos, el compilador no sabría qué variable o propiedad usar en qué situación. Por lo tanto, incluso si elige sus accesadores para que los métodos get/set no generen un conflicto, el compilador no puede permitirle usar el mismo nombre de propiedad varias veces si la firma es la misma (tenga en cuenta que puede tener varias propiedades de indexador) , porque en este caso la firma difiere, incluso con el mismo nombre). – Lucero

+3

@Lucero: ¿Y si el tipo de propiedad se impuso por el tipo de devolución del método get? En ese caso, podríamos tener instaladores de muchos tipos, el cuerpo del método de conjuntos manejando la conversión necesaria.No hay confusión para el compilador, y todavía obtenemos un tipado fuerte ya que el método set se elige según las reglas de sobrecarga del método, en lugar de tener que usar una propiedad 'object' que acepte cualquier cosa para resolver el problema (y el mío, ya que es). – paercebal

1

Un enfoque (puede discutir entre ustedes si esta es una buena opción de diseño o no) es agregar una segunda propiedad, que accede a los datos en una forma diferente.

Sin embargo, como va a analizar la cadena (haciendo un trabajo significativo), sería mejor no usar una propiedad para esto, sino agregar métodos que le permitan obtener/establecer los datos en forma de cadena .

Me gustaría ir a fieldIdList que proporciona las interfaces ToString() y TryParse() - entonces, si lo necesita como una cadena, llamaría a myObject.FieldIdList.ToString() etc. Esto encapsula todo ordenadamente, le permite convierta a/desde formatos de cadena en cualquier parte de su código, en lugar de solo acceder a FieldIdLists como miembro de alguna otra clase, y hace que el código del cliente sea realmente claro y fácil de entender.

+1

La sobrecarga de 'cadena' es un ejemplo, no el caso general. El interlocutor quiere proporcionar una sobrecarga al método establecido de una propiedad, para el tipo A y para B, cualquiera que sea su tipo. Digamos que su "conversión" al verdadero tipo subyacente de la propiedad no es "trabajo significativo". Entonces usar propiedades sería una buena solución natural en C# en mi humilde opinión. – paercebal

+0

@paercebal: como una mejor práctica, las propiedades deberían tener implementaciones triviales sin efectos secundarios: los programadores deberían ser capaces de tratar una propiedad como si fuera una simple variable miembro (es decir, suponer que su configuración será rápida/eficiente, sin pérdidas, y no generar eventos o excepciones). En cualquier otro caso, es una mejor práctica implementarlo como un método. La sobrecarga de una propiedad significa que la propiedad * es * una implementación no trivial, y que se está ocultando cierto nivel de complejidad. Esto * * no siempre será malo, pero frecuentemente lo es. –

+0

Entiendo la excusa de "mejores prácticas", pero que el compilador lo haga cumplir parece inútil y exagerado porque: '1.' Los programadores malos siempre escriben propiedades incorrectas sin importar la cantidad de limitaciones del compilador involucradas' 2.' Limita bien programadores de hacer algo que sería correcto. . . '3.' ¿Soy el único que lo encuentra divertido/contradictorio por el hecho de que una propiedad no se puede sobrecargar, pero aún se puede anular (convirtiéndola en' virtual')? – paercebal

0

Si desea poder establecer una propiedad como una cadena o un objeto, entonces simplemente usaría el objeto como el tipo de la propiedad, ya que es la clase base (puede pasar una cadena a una propiedad que acepte un objeto). Esto no parece una decisión de diseño particularmente buena, pero se puede hacer. ¿Quizás necesites explicar más a fondo lo que intentas lograr?

+3

El que pregunta fue bastante claro: ** Quiere proporcionar sobrecargas de método para el método set. ** Esto es tan legítimo como escribir múltiples métodos sobrecargados 'SetField (Field field)' y 'SetField (string field)'. – paercebal

+0

@DanDiplo Usar el objeto no es realmente útil, ya que el OP solo quiere aceptar dos tipos, una Cadena y la FieldIdList personalizada. – Marcel