Click here to Skip to main content
15,907,687 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
In the following code I defined a class Polynomial which contains an array marked readonly.
I defined a read property. A write property can not be defined because of compiler error CS0191. That is OK.
But if I try to write using (the non existing) write property for example p.Coeff[2] = 19 it works! How can that be?
I made some further tests:
A: I defined an indexer. The compiler does not prevent me from defining a write property. It can be used to modify the readonly member data.
B: I used my Polynomial object p as a parameter to the method UsePolynomial with the key word in. I understand the argument is passed by reference in order to avoid unnecessary copy operations if the parameter object will not be modified. The compiler should not allow any operations which modify the object. But there is no problem to modify p. Any changes made in the method called are available after returning from the call.
Here is my programm:
namespace PolyTest
{
    class Program
    {
        public class Polynomial
        {
            readonly private double[] coeff;
            public double[] Coeff { get => coeff;} // Does not allow set property because coeff is readonly (CS0191)
            public double this[int i] { get => coeff[i]; set => coeff[i] = value; }
            public Polynomial(double c0, double c1, double c2)
            {
                coeff = new double[] { c0, c1, c2 };
            }
        }
        static void Main(string[] args)
        {
            Polynomial p = new Polynomial(1, 2, 3);
            UsePolynomial(p);
            double val = p[2];          // val = 17 (or 18 if the last line in UsePolynomial is uncommented)
        }

        static void UsePolynomial(in Polynomial p)
        {
            double val1 = p.Coeff[2];   // val1 = 3  OK
            double val2 = p[2];         // Val2 = 3  OK
            p.Coeff[2] = 17;            // Why is that possible?
            //p[2] = 18;                  // Why is that possible?
        }
    }
}


What I have tried:

What I have tried you can read in the question.
Posted
Updated 21-Mar-20 13:03pm
v2

1 solution

The read-only only applies to the array variable itself, but not for the members of the array. You cannot change the variable and make it point to another array, that's it.

The solution to prevent modifying members of the array is to hide the array itself from outside, and get rid of the setter in index-accessor property:
C#
public class Polynomial
{
   readonly private double[] coeff;

   public double this[int i] { get => coeff[i]; }

   public Polynomial(double c0, double c1, double c2)
   {
      coeff = new double[] { c0, c1, c2 };
   }
}

This way, you cannot modify any element of the array, because from the outside there is absolutely no way to do it.
 
Share this answer
 
Comments
Member 13566383 21-Mar-20 19:12pm    
My array is private and therefore hidden from the outside. Removing the setter in index-accessor property or removing the indexer completely doesn't solve the problem.
If I do that I can still use the (not existing??) set method p.Coeff[2] = 17;
Just try it.
phil.o 21-Mar-20 19:15pm    
Yes, because you provide a property to the array itself (public double[] Coeff { get => coeff;}! Remove it and you'll be fine.
Member 13566383 21-Mar-20 19:26pm    
OK, I thought you recommended to remove my second code line in the class Polynomial and not the first.
Now the behaviour is as expected (and I even begin to understand why).

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900