1

Okay, I've this classes and main. I'm on VS 2010 Ultimate and .NET 4 Client.

internal class tezt
{
    private int[] _numeros = new int[5];
    public int[] Numeros
    {
        get { return _numeros; }
    }
}
public class tezt2
{
    private int[] _numeros = new int[5];
    public int[] Numeros
    {
        get { return _numeros; }
    }
}
class tezt3
{
    private int[] _numeros = new int[5];
    public int[] Numeros
    {
        get { return _numeros; }
    }
}
internal static class Program
{
    private static void Main()
    {
        var arrNums = new tezt();
        var arrNums2 = new tezt2();
        var arrNums3 = new tezt3();
        Console.WriteLine(arrNums.Numeros[0]);
        arrNums.Numeros[0] = 5;
        Console.WriteLine(arrNums.Numeros[0]);
        Console.WriteLine(arrNums2.Numeros[0]);
        arrNums2.Numeros[0] = 6;
        Console.WriteLine(arrNums2.Numeros[0]);
        Console.WriteLine(arrNums3.Numeros[0]);
        arrNums3.Numeros[0] = 7;
        Console.WriteLine(arrNums3.Numeros[0]);
        Console.ReadKey(true);
    }
}

What's happening with these lines:

arrNums.Numeros[0] = 5;
arrNums2.Numeros[0] = 6;
arrNums3.Numeros[0] = 7;

Isn't supposed that because the classes from which those objects are derived from haven't a set parameter, those asignations must not be allowed?

What can be done to avoid that, to restrict that, thad doing thiks like arrNums.Numeros[0] = 5; throws a error?

mishamosher
  • 1,003
  • 1
  • 13
  • 28
  • 1
    You're not setting the property. You are *getting* the array from the property and assigning to its elements. If you do not want this, do not expose an array. – Anthony Pegram Apr 25 '12 at 02:18

2 Answers2

2

You're not setting the Numeros property, you are modifying an element at an index inside that property. You are only using the getter for that property.

The assignment that isn't allowed is assigning a new value to that object's property:

arrNums.Numeros = new int[5]; // will not compile.

You could make the getter return an IEnumerable<int> to protect it:

class tezt3
{
    private int[] _numeros = new int[5];
    public IEnumerable<int> Numeros
    {
        get { return _numeros; }
    }
}

You could also use a ReadOnlyCollection. The pros and cons of using IEnumerable<T> vs ReadOnlyCollection<T> are discussed in depth in this question.

Community
  • 1
  • 1
Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
0

Can I also advice not using arrays on properties. Here is a quote from Framework Design Guidelines

Properties that return arrays can be very misleading. Usually it is necessary to return a copy of an internal array so that the user cannot change the internal state. This could lead to inefficient code.

In the following example, the Employees property is accessed twice in every iteration of the loop. That would be 2n + 1 copies for the following short code sample:

Company microsoft = GetCompanyData("MSFT");
for (int i = 0; i < microsoft.Employees.Length; i++)
{   
  if (microsoft.Employees[i].Alias == "kcwalina")
  {  ...  }
}

Brad Abrams, a annotator of the book, remarks on this pitfall:

Some of the guidelines in this book were debated and agreed on in the abstract; others were learned in the school of hard knocks. The guideline on properties that return arrays is in the school of hard knocks camp. When we were investigating some performance issues in version 1.0 of the .NET Framework, we noticed that thousands of arrays were being created and quickly trashed. It turns out that many places in the Framework itself ran into this pattern. Needless to say, we fixed those instances and the guidelines. - Brad Abrams

payo
  • 4,501
  • 1
  • 24
  • 32