Pregunta

Tengo una clase que define una propiedad de solo lectura que expone efectivamente un campo privado, algo como esto:

public class Container
{
    private List<int> _myList;

    public List<int> MyList
    {
        get { return _myList;}
    }

    public Container() : base ()
    {
        _myList = new List<int>();
    }

    // some method that need to access _myList
    public SomeMethod(int x)
    {
         _myList.Add(x);
    }
}

ahora es imposible para el consumidor administrar mi propiedad directamente, así que codifique como aContainer.MyList = new List (); genera un error en tiempo de compilación. Sin embargo, el consumidor es absolutamente libre de llamar a todo tipo de métodos en la referencia que obtuvo, por lo que este es un código perfectamente válido

Container c = new Container();  
Console.WriteLine(c.MyList.Count);  
c.MyList.Add(4);  
Console.WriteLine(c.MyList.Count);  

qué tipo de derrota todo el concepto de solo lectura.

¿Existe alguna solución sensata que me permita tener una propiedad de referencia de solo lectura real?

P.S. No puedo devolver una copia de la lista porque el usuario pensará que hizo todos los cambios necesarios, pero desgraciadamente ... se habrán ido.

¿Fue útil?

Solución

La referencia es " readonly < !> quot; , el objeto real. Es decir. No puede reemplazar la referencia con otro objeto. Entonces, si tiene una clase que la divide así:

public class Container
{
    private readonly  List<int> _myList;

    public List<int> MyList
    {
        get { return _myList;}
    }

    public Container() : base ()
    {
        _myList = new List<int>();
    }

    public void BreakReadOnly()
    {
        _myList = new List<int>();
    }
}

& # 8230; entonces ni siquiera se compilará. Es porque un campo de solo lectura no se puede reasignar con ningún otro objeto. En este caso, BreakReadOnly intentará asignar una nueva lista.

Si realmente desea una colección de solo lectura, puede hacerlo así:

    public ReadOnlyCollection<int> MyList
    {
        get { return _myList.AsReadOnly(); }
    }

Espero que esto ayude.

Actualizado : Se eliminó el uso de IEnumerable.

Otros consejos

No devuelva una referencia directa a su lista. En su lugar, devuelva una ReadOnlyCollection envuelta alrededor de ella, o si List & Lt; & Gt; El tipo de retorno está escrito en piedra, devuelva una copia de su lista. Pueden hacer lo que quieran con la copia sin afectar el original.

Puede devolver una Colección readonly como esta:

    public ReadOnlyCollection<int> MyList
    {
        get { return _myList.AsReadOnly(); }
    }

o devolver una nueva Lista para que la persona que llama pueda cambiar la lista sin cambiar la lista original.

    public List<int> MyList
    {
        get { return new List<int>(_myList)}
    }

Eche un vistazo al Array.AsReadOnly () estático. , que puede usar para devolver un contenedor alrededor de una matriz que evita que se modifique.

Desea _myList, que es un tipo de referencia de solo lectura. Bueno, es de solo lectura y no hay derrota del concepto de solo lectura.

El CLR implementa una propiedad de solo lectura para tipos de referencia de tal manera que la referencia (puntero al objeto si lo desea) es lo que se hace de solo lectura, mientras que el objeto al que apunta la referencia puede modificarse.

Para evitar esto, necesitaría hacer que los campos miembros del objeto sean de solo lectura, ya que no puede hacer que todo el objeto sea de solo lectura adjuntando un indicador de solo lectura a la referencia del objeto.

Puede implementar su clase de colección genérica inmutable que se comportaría de la misma manera que List < > objeto pero con miembros de solo lectura.

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