Pregunta

Juro que he visto un ejemplo de esto, pero he estado buscando en Google un poco y no lo encuentro.

Tengo una clase que tiene una referencia a un objeto y necesita tener un GET; Método para ello. Mi problema es que no quiero que nadie sea capaz de jugar con él, es decir, yo quiero que tengan una versión de solo lectura de la misma, (tenga en cuenta que necesito para ser capaz de alterarla desde el interior de mi clase).

Gracias

¿Fue útil?

Solución

No, no hay manera de hacer esto. Por ejemplo, si usted vuelve un List<string> (y no es inmutable), entonces las personas que llaman ser capaz de agregar entradas.

La manera normal alrededor de esto es devolver una envoltura inmutable, por ejemplo, ReadOnlyCollection<T> .

Para otros tipos mutables, es posible que necesite para clonar el valor antes de devolverlo.

Tenga en cuenta que acaba de regresar de una vista de la interfaz inmutable (por ejemplo, volviendo IEnumerable<T> en lugar de List<T>) no se detendrá una persona que llama desde la fundición de nuevo al tipo mutable y mutando.

EDIT: Tenga en cuenta que, aparte de todo lo demás, este tipo de preocupación es una de las razones por las cuales los tipos inmutables hacen que sea más fácil para razonar sobre el código:)

Otros consejos

devolver una referencia a una interfaz despojada:

 interface IFoo
   string Bar { get; }

 class ClassWithGet
   public IFoo GetFoo(...);

Esto no es posible. Obtener y establecer métodos de acceso para hacer referencia a tipos obtener y establecer la referencia al objeto. Puede evitar cambios en la referencia mediante el uso de un regulador privada (o interna), pero no se puede evitar que los cambios en el objeto en sí mismo si está expuesto por un captador.

Si el objeto no es demasiado complicado / extensa luego escribir una envoltura alrededor de ella.

por ejemplo:

class A {
    public string strField = 'string';
    public int intField = 10;
}

class AWrapper {
    private A _aObj;

    public AWrapper(A aobj) {
      _aObj = A;
    }

    public string strField {
         get {
            return _aObj.strField;
         }
    }

    public int intField {
         get {
            return _aObj.intField;
         }
    }
}

Así que ahora todo lo que hacen es dar a su código de cliente de una instancia de la clase AWrapper para que sólo se pueden usar lo que les permite ver.

esto puede ser un poco complicado y no puede escalar bien si la clase base no está escrito en piedra, pero para la mayoría simple situación que sólo puede hacer el truco. Creo que esto se llama un patrón de fachada (pero no me cito en ese =))

Su pregunta se lee como que estás buscando:

public PropertyName { get; private set; }

Pero entonces, dadas las respuestas hasta el momento no estoy seguro de que estoy interpretando bien su pregunta. Además, ¿quién soy yo para cuestionar Jon Skeet? :)

Estoy de acuerdo con ReadOnlyCollection

Vea mi código simple:

 private List<Device> _devices;
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices 
{
 get
 { 
return (_devices.AsReadOnly());
 } 

}

dosis no tiene ReadOnlyCollection Añadir método para que el usuario no puede añadir propiedades a it.But allí hay garantía de que si el usuario puede modificar los objetos llamando a sus métodos ....

Me he enfrentado a este problema de una manera determinada. Tengo una clase CategoryViewModel, que tiene una categoría de propiedad privada que quiero sólo lectura:

public CategoryViewModel
{
    private Category { get; }

}

De hecho, yo quiero que se exporta como de sólo lectura a otra clase. Sin embargo no puedo hacer tal cosa. En mi caso (tal vez pueda ayudar a otros hombres), quiero añadirlo a un repositorio. La única forma que he encontrado es tener una función con el repositorio como parámetro 1, y una acción como parámetro 2:

public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action)
{
    action(repo, Category);
}

Al igual que, de otra parte, no puedo hacer tal cosa:

 categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c));

Esto puede ayudar a otra para exponer allí la propiedad sólo para los casos certains y puede manejarlos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top