“const correctness” in C#

前端 未结 7 1432
执念已碎
执念已碎 2020-11-28 05:29

The point of const-correctness is to be able to provide a view of an instance that can\'t be altered or deleted by the user. The compiler supports this by pointing out when

相关标签:
7条回答
  • 2020-11-28 05:31
    • The const keyword can be used for compile time constants such as primitive types and strings
    • The readonly keyword can be used for run-time constants such as reference types

    The problem with readonly is that it only allows the reference (pointer) to be constant. The thing referenced (pointed to) can still be modified. This is the tricky part but there is no way around it. To implement constant objects means making them not expose any mutable methods or properties but this is awkward.

    See also Effective C#: 50 Specific Ways to Improve Your C# (Item 2 - Prefer readonly to const.)

    0 讨论(0)
  • 2020-11-28 05:37

    C# doesn't have such feature. You can pass argument by value or by reference. Reference itself is immutable unless you specify ref modifier. But referenced data isn't immutable. So you need to be careful if you want to avoid side effects.

    MSDN:

    Passing Parameters

    0 讨论(0)
  • 2020-11-28 05:37

    Interfaces are the answer, and are actually more powerful than "const" in C++. const is a one-size-fits-all solution to the problem where "const" is defined as "doesn't set members or call something that sets members". That's a good shorthand for const-ness in many scenarios, but not all of them. For example, consider a function that calculates a value based on some members but also caches the results. In C++, that's considered non-const, although from the user's perspective it is essentially const.

    Interfaces give you more flexibility in defining the specific subset of capabilities you want to provide from your class. Want const-ness? Just provide an interface with no mutating methods. Want to allow setting some things but not others? Provide an interface with just those methods.

    0 讨论(0)
  • 2020-11-28 05:40

    I just wanted to note for you that many of the System.Collections.Generics containers have an AsReadOnly method which will give you back an immutable collection.

    0 讨论(0)
  • 2020-11-28 05:41

    I've come across this issue a lot of times too and ended up using interfaces.

    I think it's important to drop the idea that C# is any form, or even an evolution of C++. They're two different languages that share almost the same syntax.

    I usually express 'const correctness' in C# by defining a read-only view of a class:

    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; }
        }
    }
    
    0 讨论(0)
  • 2020-11-28 05:44

    Agree with some of the others look at using readonly fields that you initialize in the constructor, to create immutable objects.

        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; }
        }
      }
    

    Alternatively you could also add access scope on the properties, i.e. public get and protected set?

        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; }
        }
      }
    
    0 讨论(0)
提交回复
热议问题