is this possible? an indexed property to have sub-properties?

M

Michael Matteson

I have two classes. Class
A and Class B. I give class A 5 properties
int prop1(){}
int prop2(){}
int prop3(){}
int prop4(){}
classB prop5(){}

what i would like to do is to create a 5th property and make its type equal
to ClassB. but i would also like to index this property too. BTW Class B
also has some properties to it. So in the end i would be able to access my
items like this:

classA xyz = new classA();
xyz.prop1=1;
xyz.prop2=2;
xyz.prop3=3;
xyz.prop4=4;

xyz.prop5[0].prop1=1;
xyz.prop5[0].prop2=2;

xyz.prop5[1].prop1=1;
xyz.prop5[1].prop2=2;

I remember doing stuff like this a while ago in VB6 but i'm pretty new to C#
and i'm just learning out to do this sort of stuff. I hope that explain
helps a little bit more.
 
B

Bruce Wood

Michael said:
I have two classes. Class
A and Class B. I give class A 5 properties
int prop1(){}
int prop2(){}
int prop3(){}
int prop4(){}
classB prop5(){}

what i would like to do is to create a 5th property and make its type equal
to ClassB. but i would also like to index this property too. BTW Class B
also has some properties to it. So in the end i would be able to access my
items like this:

classA xyz = new classA();
xyz.prop1=1;
xyz.prop2=2;
xyz.prop3=3;
xyz.prop4=4;

xyz.prop5[0].prop1=1;
xyz.prop5[0].prop2=2;

xyz.prop5[1].prop1=1;
xyz.prop5[1].prop2=2;

I remember doing stuff like this a while ago in VB6 but i'm pretty new to C#
and i'm just learning out to do this sort of stuff. I hope that explain
helps a little bit more.

I'm assuming from your examples that ClassB is some sort of aggregate
for which indexing makes sense.

Just implement an indexer for ClassB (within class B) and you'll be
able to do what you indicated.

http://msdn2.microsoft.com/en-us/library/2549tw02.aspx
 
M

Michael Matteson

yea my real world situation is this. i'm receiving netflow packets from a
cisco device and storing them in a class that represents the packet layout.
i call this p.

p.header property is an instantiantion on my header class that has
properties so i can store my packet header data
p.header.version
p.header.count
p.header.sysuptime
etc.

that part is fine. the next part is to store template flows.
p.templaterecord.id=1
p.templaterecord.fsid=255
p.templaterecord.length=182


but there can be many different templates included in a packet and since i
don't know how many i just wanted to create an array (indexed property) to
store my templaterecord data. so later on i can just for/each through it and
write the data to a database. i'll give what you said a try. thanks bruce!

Bruce Wood said:
Michael said:
I have two classes. Class
A and Class B. I give class A 5 properties
int prop1(){}
int prop2(){}
int prop3(){}
int prop4(){}
classB prop5(){}

what i would like to do is to create a 5th property and make its type
equal
to ClassB. but i would also like to index this property too. BTW Class B
also has some properties to it. So in the end i would be able to access
my
items like this:

classA xyz = new classA();
xyz.prop1=1;
xyz.prop2=2;
xyz.prop3=3;
xyz.prop4=4;

xyz.prop5[0].prop1=1;
xyz.prop5[0].prop2=2;

xyz.prop5[1].prop1=1;
xyz.prop5[1].prop2=2;

I remember doing stuff like this a while ago in VB6 but i'm pretty new to
C#
and i'm just learning out to do this sort of stuff. I hope that explain
helps a little bit more.

I'm assuming from your examples that ClassB is some sort of aggregate
for which indexing makes sense.

Just implement an indexer for ClassB (within class B) and you'll be
able to do what you indicated.

http://msdn2.microsoft.com/en-us/library/2549tw02.aspx
 
B

Bruce Wood

A word of caution about returning aggregates as properties.

There are two simple-minded ways to return aggregates as properties,
both of which can result in problems. The "right" way to do it is more
complex. I put "right" in quotation marks because, of course, nothing
is right in all situations.

Most people start out making aggregate properties doing something like
this:

public class ClassA
{
private string[] _stuff;

public string[] Stuff { get { return this._stuff; } }
}

Seems simple enough. The only problem is that because arrays are passed
(and returned) by reference, this code just gave its callers the power
to modify the object's internal state without any controls. So, for
example, a caller could do this:

ClassA a = new ClassA();
a.Stuff[15] = "Hello world";

While the caller cannot replace the entire array (because Stuff has no
setter), a caller _can_ modify the _contents_ of the array, and perhaps
that's not what the class intended (many classes want to export a
read-only aggregate).

So, the programmer gets trickier:

public class ClassA
{
private string[] _stuff;

public string[] Stuff { get { return (string[])this._stuff.Clone();
} }
}

Now the caller just gets a copy and can't change the ClassA object's
internal state without ClassA knowing about it. This, however, can lead
to efficiency problems when callers (perfectly reasonably) do things
like this:

ClassA a = new ClassA();
for (int i = 0; i < a.Stuff.Length; i++)
{
string s = a.Stuff;
...
}

because here the Stuff array is cloned at least once (and perhaps
twice) for each time around the loop. Nasty.

The "correct" solution is along the lines of what you posted: create a
new class to represent the aggregate structure, and have _that class_
decide what the caller may or may not do with the aggregate.

Look, for example, at how ListViewItemCollection is implemented as a
model.

Michael said:
yea my real world situation is this. i'm receiving netflow packets from a
cisco device and storing them in a class that represents the packet layout.
i call this p.

p.header property is an instantiantion on my header class that has
properties so i can store my packet header data
p.header.version
p.header.count
p.header.sysuptime
etc.

that part is fine. the next part is to store template flows.
p.templaterecord.id=1
p.templaterecord.fsid=255
p.templaterecord.length=182


but there can be many different templates included in a packet and since i
don't know how many i just wanted to create an array (indexed property) to
store my templaterecord data. so later on i can just for/each through it and
write the data to a database. i'll give what you said a try. thanks bruce!

Bruce Wood said:
Michael said:
I have two classes. Class
A and Class B. I give class A 5 properties
int prop1(){}
int prop2(){}
int prop3(){}
int prop4(){}
classB prop5(){}

what i would like to do is to create a 5th property and make its type
equal
to ClassB. but i would also like to index this property too. BTW Class B
also has some properties to it. So in the end i would be able to access
my
items like this:

classA xyz = new classA();
xyz.prop1=1;
xyz.prop2=2;
xyz.prop3=3;
xyz.prop4=4;

xyz.prop5[0].prop1=1;
xyz.prop5[0].prop2=2;

xyz.prop5[1].prop1=1;
xyz.prop5[1].prop2=2;

I remember doing stuff like this a while ago in VB6 but i'm pretty new to
C#
and i'm just learning out to do this sort of stuff. I hope that explain
helps a little bit more.

I'm assuming from your examples that ClassB is some sort of aggregate
for which indexing makes sense.

Just implement an indexer for ClassB (within class B) and you'll be
able to do what you indicated.

http://msdn2.microsoft.com/en-us/library/2549tw02.aspx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top