que - c#objeto de solo lectura
que es get en programacion (8)
¿Hay alguna forma de devolver una instancia de solo lectura de un objeto?
public class Person
{
public String FirstName { get; set; }
public String LastName { get; set; }
}
public class SomeClass
{
public SomeClass(Person manager)
{
if (manager == null)
throw new ArgumentNullException("manager");
_manager = manager;
}
private readonly Person _manager;
public Person Manager
{
get { return _manager; } //How do I make it readonly period!
}
}
¿Es la única forma de hacer esto devolviendo un Clone () para que se realicen cambios al Clone y no al original? Sé que para Arrays hay una función para devolver el Array como de solo lectura. Ah, y sé que este es un tipo de referencia ... Además, me pregunto si hay alguna característica oculta de C # para bloquear la parte de escritura.
Estaba tratando de encontrar una clase de envoltura genérica ReadOnly, pero no podía encontrar la forma de obtener las propiedades de solo lectura sin hacer una reflexión costosa y demás.
Ah, y realmente estoy tratando de evitar crear una segunda versión de la clase que sea de solo lectura. En ese momento, también podría devolver el clon.
Aquí hay otro ejemplo, basado en cómo se implementa List.AsReadOnly en .NET Framework 2.0. Un booleano (IsReadOnly) se utiliza en métodos apropiados para evitar actualizaciones:
public class Person
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
if (!IsReadOnly) _firstName = value;
else throw new AccessViolationException("Object is read-only.");
}
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
if (!IsReadOnly) _lastName = value;
else throw new AccessViolationException("Object is read-only.");
}
}
internal virtual bool IsReadOnly { get { return false; } }
public ReadOnlyPerson AsReadOnly()
{
return new ReadOnlyPerson(this);
}
public class ReadOnlyPerson : Person
{
private Person _person;
internal override bool IsReadOnly { get { return true; } }
internal ReadOnlyPerson(Person person) // Contructor
{
this._person = person;
}
}
}
Para probarlo:
static void Main(string[] args)
{
Person p1 = new Person();
p1.FirstName = "Joe";
p1.LastName = "Bloe";
Console.WriteLine("First = {0} Last = {1}", p.FirstName, p.LastName);
var p2 = p1.AsReadOnly();
p2.FirstName = "Josephine"; // AccessViolationException
}
Los objetos anónimos son de solo lectura.
No hay tal característica, has cubierto tus opciones.
Clone o haga un tipo de Person
solo lectura. Este último enfoque suele ser preferido porque la semántica es más clara: es obvio para los llamadores que no deberían (y no pueden) modificar la instancia.
No hay una manera de hacer que todas las propiedades de su objeto sean de una sola lectura externa desde la clase. En su ejemplo anterior, no puede hacer que las propiedades _manager sean de solo lectura, a menos que haya cambiado las propiedades dentro de la clase Persona para que sean de solo lectura.
Puede hacer que el setter de propiedades de la clase Person sea interno, lo que significa que solo las clases dentro del mismo conjunto que Person pueden cambiar las propiedades.
O, si hace que el establecedor de las propiedades sea privado, solo el código dentro de Persona puede cambiar los valores de las propiedades.
Para evitar la creación de una clase adicional, puede hacer que se implemente como una interfaz IPerson que solo tiene propiedades de solo lectura.
public interface IPerson
{
string FirstName { get; }
string LastName { get; }
}
public class Person:IPerson
{
public String FirstName { get; set; }
public String LastName { get; set; }
}
public class SomeClass
{
public SomeClass(Person manager)
{
if (manager == null)
throw new ArgumentNullException("manager");
_manager = manager;
}
private readonly Person _manager;
public IPerson Manager
{
get { return _manager; } //How do I make it readonly period!
}
}
Puede congelar el objeto (hacerlo inmutable) bajo ciertas condiciones con la ayuda de Castle.DynamicProxy
. Lea esta publicación del blog para más detalles.
Puede transformar la clase Persona en un objeto inmutable, como se muestra a continuación.
public class Person
{
public Person( string firstName, string lastName )
{
FirstName = firstName;
LastName = lastName;
}
public String FirstName { get; private set; }
public String LastName { get; private set; }
}