Groups | Blog | Home
all groups > dotnet framework > december 2007 >

dotnet framework : private array member still public...?



Peter Duniho
12/30/2007 9:05:50 PM
[quoted text, click to view]
s =

[quoted text, click to view]
=

[quoted text, click to view]
y?

If I understand your goal correctly, you can't really do exactly what yo=
u =

want while preserving the PointF[] semantics. But you can get very clos=
e.

In C#, you can create an indexed property:

PointF this[int ipt]
{
get { return vtx[ipt]; }
set { vtx[ipt] =3D value; }
}

See: http://msdn2.microsoft.com/en-us/library/2549tw02(VS.80).aspx

Using that syntax, you can either make your main class have the indexer,=
=

or more likely you'll want to create a specific class to hold the vertex=
=

array, which has an indexed property like that, and which you expose as =
a =

regular property in the main class.

The former is simpler, but creates what IMHO is an awkward syntax if the=
=

main class isn't itself something that is semantically an abstracted lis=
t =

of points. The latter is more complicated, but can more correctly =

represent the intent behind the design, assuming this list of points is =
=

but one of many things the main class contains and exposes.

Either way, it allows you to completely hide the underlying implementati=
on =

and require the client of your class to access the elements through your=
=

own indexer, giving you the opportunity to include whatever specific =

restrictions you like. Of course, even if your only goal is to hide the=
=

underlying array, it works fine for that too.

[quoted text, click to view]
=

[quoted text, click to view]
=

[quoted text, click to view]

How to fix what? The two problems are not really related. If you are =

asking a second question, regarding how to ensure that the array being =

assigned is compatible with the intent, in your sample code you could lo=
ok =

at the Length property of "value" before assigning it:

set
{
if (value.Length !=3D 3)
{
throw new InvalidArgumentException("array must have exactly=
3 =

elements");
}

vtx =3D value;
SetBounds();
}

Peter Duniho
12/30/2007 9:20:14 PM
[quoted text, click to view]

Why not? As long as the nested class keeps a reference to the containing
class, it should be able to call whatever method you need it to.

Alternatively (and probably a better design anyway) would be for the
nested class to declare an event that's raised when the indexer's setter
is called. Then the containing class can just subscribe to it. Much more
general-purpose, and would allow the subordinate class to not even be a
nested class in case you wanted to use it elsewhere.

bern11
12/30/2007 11:28:14 PM
I have a class with a 3 point array which I want to protect through
encapsulation. Unfortunately, the following does not do what I want:
private PointF[] vtx = new PointF[3];
public PointF[] Vtx
{
get { return vtx; }
set
{
vtx = value;
SetBounds();
}
}

I want to call the 'set' member whenever an individual array element is
called. As it is, this statement:
myObject.Vtx[0] = 10;
does not call the 'set' accessor, even though a statement such as this
calls the 'get' accessor:
x = myObject.Vtx[0];

So, how do I encapsulate access to individual members of a member array?

In hindsight, it is clear that my declaration is screwed up, since the
'set' declaration would only work if value were a 3 point array, not a
bern11
12/31/2007 12:03:41 AM
PS - indexers don't seem to work for me. This is an array member in a
class that has to exectute another member function. If I nest it so the
indexer works, I can't reference the class function SetBounds....


[quoted text, click to view]
AddThis Social Bookmark Button