propiedades property microsoft implemented c# c#-3.0 struct automatic-properties

c# - property - Las propiedades y estructuras automáticas no se mezclan?



property c# get set (3)

Desde C # 6 en adelante: esto ya no es un problema

En Becore C # 6, debe llamar al constructor predeterminado para que funcione:

public MyStruct(int size) : this() { Size = size; }

Un problema más grande aquí es que tienes una estructura mutable. Esto nunca es una buena idea Yo lo haría:

public int Size { get; private set; }

No es técnicamente inmutable, pero lo suficientemente cerca.

Con las versiones recientes de C #, puede mejorar esto:

public int Size { get; }

Esto ahora solo se puede asignar en el constructor.

Pateando alrededor de algunas estructuras pequeñas mientras respondía esta publicación , me encontré con lo siguiente inesperadamente:

La siguiente estructura, usando un campo int es perfectamente legal:

struct MyStruct { public MyStruct ( int size ) { this.Size = size; // <-- Legal assignment. } public int Size; }

Sin embargo, la siguiente estructura, que utiliza una propiedad automática no compila:

struct MyStruct { public MyStruct ( int size ) { this.Size = size; // <-- Compile-Time Error! } public int Size{get; set;} }

El error que se devuelve es "El objeto ''este'' no se puede usar antes de que se asignen todos sus campos". Sé que este es el procedimiento estándar para una estructura: el campo de respaldo para cualquier propiedad debe asignarse directamente (y no a través del acceso de conjunto de la propiedad) desde el constructor de la estructura.

Una solución es usar un campo de respaldo explícito:

struct MyStruct { public MyStruct(int size) { _size = size; } private int _size; public int Size { get { return _size; } set { _size = value; } } }

(Tenga en cuenta que VB.NET no tendría este problema, porque en VB.NET todos los campos se inicializan automáticamente a 0 / null / false cuando se crean por primera vez.)

Esto parece ser una limitación desafortunada cuando se usan propiedades automáticas con estructuras en C #. Pensando conceptualmente, me preguntaba si este no sería un lugar razonable para que exista una excepción que permita llamar al descriptor del conjunto de propiedades dentro del constructor de una estructura, al menos para una propiedad automática.

Este es un problema menor, casi un caso marginal, pero me preguntaba qué pensaban los demás sobre esto ...


Otra solución oscura a este problema es una detectada en la clase Tuple temporal en el Marco de Extensibilidad Administrada (a través de Krzysztof Koźmic ):

public struct TempTuple<TFirst, TSecond> { public TempTuple(TFirst first, TSecond second) { this = new TempTuple<TFirst, TSecond>(); // Kung fu! this.First = first; this.Second = second; } public TFirst First { get; private set; } public TSecond Second { get; private set; }

(Código fuente completo de Codeplex: Tuple.cs )

También observo que la documentación para CS0188 se ha actualizado para agregar:

Si ve este error al intentar inicializar una propiedad en un constructor de estructura, la solución es cambiar el parámetro de constructor para especificar el campo de respaldo en lugar de la propiedad en sí. Se deben evitar las propiedades implementadas automáticamente en las estructuras porque no tienen campo de respaldo y, por lo tanto, no se pueden inicializar de ninguna manera desde el constructor.

Así que entiendo que quiere decir que la orientación oficial es utilizar propiedades de estilo antiguo en sus estructuras cuando se encuentra con este problema, que probablemente es menos oscuro (y más fácil de leer) que cualquiera de las otras dos alternativas exploradas hasta ahora.


Puede solucionar esto llamando primero al constructor predeterminado:

struct MyStruct { public MyStruct(int size) : this() { this.Size = size; // <-- now works } public int Size { get; set; } }