C # readonly vs Get

¿Hay alguna diferencia entre el modificador de solo lectura y las propiedades de obtener solo?

Ejemplo:

public class GetOnly { public string MyProp { get; } } public class ReadOnly { public readonly string MyProp; } 

Bonus: ¿hay una manera de hacer una interfaz que funcione con ambos? (para usar con generics)

 public interface ISomething { public string MyProp { get; } } public class GetOnly : ISomething { public string MyProp { get; } } public class ReadOnly : ISomething // Cannot implement { public readonly string MyProp; } 

¡Muchas gracias de antemano!

A primera vista, la propiedad y el campo son funcionalmente equivalentes y para los casos de uso normal de almacenamiento de datos y su transferencia no hay mucha diferencia en su uso.

Pero parece que ya ha encontrado un problema importante: solo las propiedades pueden formar parte de una interfaz.

¿Hay una manera de hacer una interfaz que funcione con ambos?

No.

Además, muchas API que se basan en la reflexión (EF, serialización) buscan específicamente propiedades.

Fundamentalmente estás malinterpretando el significado de ambas definiciones. Solo exponer al captador no dice nada sobre si un valor es de solo lectura.

Mientras que en este ejemplo trivial:

 public class GetOnly { public string MyProp { get; } } 

Podemos decir que MyProp nunca cambiará su valor, no siempre podemos decir que una propiedad exclusiva para los captadores no cambiará su valor. Un ejemplo de esto es una situación en la que no podemos ver la implementación de GetOnly y solo conocer la definición pública; por ejemplo, si estaba trabajando con una biblioteca de terceros de código cerrado.

Un ejemplo más claro es el siguiente:

 public interface ISomething { string MyProp { get; } } 

Esta interfaz no dice que MyProp es de solo lectura. Dice que no puedes cambiar la propiedad. No dice nada sobre el comportamiento de la propiedad. Peor aún, solo dice que no se puede cambiar la propiedad cuando se ISomething explícitamente como ISomething .

Es totalmente posible implementar la interfaz así (aunque la interfaz solo expone al captador):

 public class GetOnly : ISomething { public string MyProp { get; set; } } 

readonly es un modificador que impone explícitamente el hecho de que el valor no cambiará nunca, excepto en la statement o el constructor (salvo soluciones alternativas como la reflexión ).

Sin embargo, readonly no puede funcionar en las propiedades, ya que las propiedades son simplemente azúcar sintáctica para los métodos get / set. Además, las interfaces solo definen métodos y, como tal, no puede definir campos (y, por extensión, campos de solo lectura).

Entonces, para responder a tu respuesta: sí, son mundos separados y solo son similares en la superficie.

Uno es un campo ( readonly ); el otro es una propiedad. Las interfaces no pueden definir campos, solo propiedades, métodos, indexadores y eventos.

Ambos solo pueden asignarse a través de la inicialización del constructor o del campo, y no se pueden cambiar posteriormente.

En la siguiente parte:

 public class GetOnly { public string MyProp {get; } } 

MyProp es una propiedad . Sin embargo, en esta parte:

 public class ReadOnly { public readonly string MyProp; } 

MyProp es un campo . Estas son dos cosas diferentes.

¿Hay una manera de hacer una interfaz que funcione con ambos?

No. Solo las propiedades pueden ser puestas en interfaces. Los campos no pueden.