So, I've written a class, and one of the attributes of the class is an array of elements. For the sake of simplicity, say it's like this:

public class Arrays
{
     private int[] myArray = new int[5];

}

Now, I know if I just make it public, I can access it like this:

Arrays a = new Arrays();

// do something to fill the array.
...

foreach (int i in a)
{
     Console.WriteLine( "{0}", i);
}

But, the thing is, I want to keep the array private and use a public accessor to access the elements of the array. I know normally, were it not an array, you'd just use get and set accessor methods to return or set the values of the variable.

How would I create a public attribute in my class to access elements in an array? Later on, the elements might come from a database, or something, so I want to be able to use "true" data hiding and keep the actual array private.

Hi, i don't know exactly what you want to do there, but if you want only to make your int array public by a property you could do this in your class:

public int[] MyArray
{
	get
	{
		return myArray;
	}
}

Then when you want to call it:

Arrays a = new Arrays();
			
foreach (int i in a.MyArray)
{
	MessageBox.Show(this, i.ToString());
}

That actually looks a lot like what I'm shooting for. I really just want to provide access to the array through a property.

I think what was hanging me up is that I was trying to pass the index of the array into the public variable, too.

So, let me make sure I understand this code. Could I type in say,

Arrays a = new Arrays();

//... do some stuff to populate the array

int foo;
foo = a.MyArray[3];

Can I still reference that by the indexer? When the accessor returns myArray, does it pass the index I've supplied to the object?

Yes, and to populate the int array of the Arrays class you could either pass an int array in the ctor of the Arrays class or expose a setter via the MyArray property.

Hi,

All those code are valid but they aren't encapsulation really. The purpose of encapsulation is to provide a layer of decoupling between the private variable and other objects which access them. Setting a public property to return a reference to the private int array has no benefit at all but have overhead. What you need to do is to use a real indexer so it won't be possible to access the inner data directly and have references to it hanging around. When the encapsulating instance fall out of scope or you set it to Null to destroy, it wouldn't get garbage collected if there are references to the inner variables hanging around. (Actually the inner variables (private array in this case) won't get GCed.) Below is a simple indexer implementation for string array

using System;
using System.Collections;

class MyClass
{
 private string []data = new string[5];
 public string this [int index]
 {
  get  {
   return data[index];
  }
  set  {
   data[index] = value;
  }
 }
}

Loren Soth

Hi,

All those code are valid but they aren't encapsulation really. The purpose of encapsulation is to provide a layer of decoupling between the private variable and other objects which access them. Setting a public property to return a reference to the private int array has no benefit at all but have overhead. What you need to do is to use a real indexer so it won't be possible to access the inner data directly and have references to it hanging around. When the encapsulating instance fall out of scope or you set it to Null to destroy, it wouldn't get garbage collected if there are references to the inner variables hanging around. (Actually the inner variables (private array in this case) won't get GCed.) Below is a simple indexer implementation for string array

using System;
using System.Collections;

class MyClass
{
 private string []data = new string[5];
 public string this [int index]
 {
  get  {
   return data[index];
  }
  set  {
   data[index] = value;
  }
 }
}

Loren Soth

Awesome!

So I think this is more along the lines of what I'm looking for. Now, in this regard, it's become a collection, not so much an array, right? Is this its own variable type?

Would you be so kind as to provide an example as to how I'd instantiate and use that variable? I'll take a crack-- tell me if I'm wrong:

MyClass s = new MyClass();
s = {"a", "b", "c", "d", "e"}

for (i = 0, i <= s.GetCount() - 1, i++)
{
     Console.WriteLine(s[i]);
}

For the sake of argument, let's assume we had put in a method to get the count of entries, ie, GetCount() .

Does that look right, or have I missed the point?

Hi,

As you see is a direct descendent of System.Object thus it isn't an array or a collection. So you can't assign s = {"a", "b", "c", "d", "e"}. To make the class itself a collection you must implement interfaces like IColelction, IList and IEnumerable. What we have done was to declare a property with and index for array like access w/o exposing internal array or elements of it. If you just need an integer collection you can use Collection or ArrayList classes and if you need to customize them you can sub-class them.

Loren Soth

Ok, I think I have the idea now.

But, since you've got a get() accessor, you could go through and do

s[0] = "a";
s[1] = "b";

//etc  .

right? If so, that would suit my needs just fine.

This article has been dead for over six months. Start a new discussion instead.