Pregunta "Const correctness" en C #


El punto de corrección const es poder proporcionar una vista de una instancia que no puede ser alterada o eliminada por el usuario. El compilador lo admite señalando cuándo se rompe la constness desde dentro de una función const, o intenta usar una función no const de un objeto const. Entonces, sin copiar el enfoque const, ¿hay alguna metodología que pueda usar en C # que tenga los mismos fines?

Soy consciente de la inmutabilidad, pero eso realmente no se traslada a los objetos contenedores, por poner un ejemplo.


75
2017-09-22 10:25


origen


Respuestas:


También me he topado con este tema muchas veces y terminé usando interfaces.

Creo que es importante descartar la idea de que C # sea de cualquier forma, o incluso una evolución de C ++. Son dos idiomas diferentes que comparten casi la misma sintaxis.

Por lo general, expreso 'const correctness' en C # definiendo una vista de solo lectura de una clase:

public interface IReadOnlyCustomer
{
    String Name { get; }
    int Age { get; }
}

public class Customer : IReadOnlyCustomer
{
    private string m_name;
    private int m_age;

    public string Name
    {
        get { return m_name; }
        set { m_name = value; }
    }

    public int Age
    {
        get { return m_age; }
        set { m_age = value; }
    }
}

59
2017-09-22 13:19



Para obtener el beneficio de la locura const (o pureza en términos de programación funcional), tendrá que diseñar sus clases de manera que sean inmutables, al igual que la clase String de c # is.

Este enfoque es mucho mejor que simplemente marcar un objeto como de solo lectura, ya que con las clases inmutables puede pasar datos fácilmente en entornos de tareas múltiples.


28
2017-09-22 10:45



Solo quiero señalar para usted que muchos de los contenedores de System.Collections.Generics tienen un método AsReadOnly que le devolverá una colección inmutable.


23
2017-09-23 13:40



C # no tiene esa característica. Puede pasar argumentos por valor o por referencia. La referencia en sí es inmutable a menos que especifique árbitro modificador Pero los datos a los que se hace referencia no son inmutables. Por lo tanto, debe tener cuidado si desea evitar los efectos secundarios.

MSDN:

Pasar parámetros


4
2017-09-22 10:30



Las interfaces son la respuesta, y en realidad son más poderosas que "const" en C ++. const es una solución única para el problema donde "const" se define como "no establece miembros o llama a algo que establece miembros". Esa es una buena forma abreviada de const-ness en muchos escenarios, pero no en todos. Por ejemplo, considere una función que calcula un valor basado en algunos miembros pero también almacena en caché los resultados. En C ++, eso se considera no const, aunque desde la perspectiva del usuario es esencialmente const.

Las interfaces le dan más flexibilidad para definir el subconjunto específico de capacidades que desea proporcionar de su clase. ¿Quieres const-ness? Solo proporcione una interfaz sin métodos de mutación. ¿Quieres permitir configurar algunas cosas pero no otras? Proporcione una interfaz con solo esos métodos.


3
2017-09-22 17:33



Acuerde con algunos de los otros mirar usando campos de solo lectura que inicializa en el constructor, para crear objetos inmutables.

    public class Customer
    {
    private readonly string m_name;
    private readonly int m_age;

    public Customer(string name, int age)
    {
        m_name = name;
        m_age = age;
    }

    public string Name
    {
        get { return m_name; }
    }

    public int Age
    {
        get { return m_age; }
    }
  }

Alternativamente, también podría agregar el alcance de acceso a las propiedades, es decir, obtener público y conjunto protegido?

    public class Customer
    {
    private string m_name;
    private int m_age;

    protected Customer() 
    {}

    public Customer(string name, int age)
    {
        m_name = name;
        m_age = age;
    }

    public string Name
    {
        get { return m_name; }
        protected set { m_name = value; }
    }

    public int Age
    {
        get { return m_age; }
        protected set { m_age = value; }
    }
  }

3
2017-09-25 11:26



  • los const la palabra clave se puede usar para constantes de tiempo de compilación, como tipos primitivos y cadenas
  • los solo lectura la palabra clave se puede usar para las constantes de tiempo de ejecución, como los tipos de referencia

El problema con solo lecturaes que solo permite que la referencia (puntero) sea constante. La cosa a la que se hace referencia (apuntada) aún se puede modificar. Esta es la parte difícil, pero no hay forma de evitarla. Implementar objetos constantes significa hacer que no expongan ningún método o propiedad mutable, pero esto es incómodo.

Ver también Eficaz C #: 50 formas específicas para mejorar su C # (Artículo 2 - Prefiero leer solo a const.)


2
2017-09-22 12:32