blah blah blah is here! blah blah » Close

up0down
link

My goal: To define a custom class indexer to take the place of an underlying Hashtable member so that values can be referred to as Class1[index] instead of Class1.someVar[index].
The following code does not work & I believe I understand why (a value is returned by my indexer, not a reference). Does anyone have any insight into how to achieve my goal given the following code? The answer could be as simple as "don't use a hashtable!", but I'm hoping there's just an interface or alternate definition that I can implement. I've changed my class names to protect the innocent...
//Class 1 definition
class ClownCar{
private Hashtable Clowns = new Hashtable();
//...code omitted
//Properties
public Clown this [int index] {
get {
if (index < 0 || index >= Clowns.Count)
throw new Exception("Index outside the range of valid values.");
else
return (Clown)Clowns[index];
}
set {
if (index < 0 || index >= Clowns.Count)
throw new Exception("Index outside the range of valid values.");
else
Clown[index] = value;
}
}
//Class 2 definition
class Clown{
bool CanJuggle = true;
//...code omitted
}
//client script tries to set an indexer's data
ClownCar RedClownCar = new ClownCar();
//...code omitted
//the following line of code does jack sh*t to the referenced object (i.e. varClass[0]'s internal values will remain the same).
RedClownCar[0].CanJuggle= false;

last answered 2 years ago

1 answers

up0down
link

Why don't you simply use an ArrayList instead of a Hashtable? In any rate, you need to add the Clown objects to the data structure before you can assign a value to it:
ClownCar cc = new ClownCar();
cc.Items.Add(new Clown()); // IMPLEMENT THE ADD METHOD!
...
cc[0].CanJuggle = false;

up0down
link

VBGuy, I implemented the Add() in the "//code omitted" section, I wanted the example to be as clean as possible. In your example, tye cc[0].CanJuggle won't actually do anything, though, because of the way I implemented my indexer. cc[0] will return a Clown object which apparently can be used to assign values to other Clowns but won't actually keep any changes.
Help!

up0down
link

did this ever get resolved?
I found you cant reference the item by a numeric index because they aren't stored exactly that way, unless you iterate through the hashtable. I've been doing something similar lately and this post came to mind... also the set would need to be something like:else clowns.Add(indexValue, value);
if you did get it resolved what did you do?

up0down
link

Nope, never resolved. If I remember correctly, I just switched back to exposing a public array of Clown objects in the ClownCar class.
I was actually thinking about this recently, too, and I think if I had to do it again, I'd try to implement a ClownCollection class and have the indexer of a ClownCar expose that. I didn't realize until recently that so many of the Framework behaviors I take for granted use this approach. For instance, DataTable1.Rows[0] doesn't access an array of rows, but a RowCollection object, which handles the behind-the-scenes work that wasn't working for me at all with my initial approach.
Any thoughts on that?

up0down
link

recently I wrote a wrapper for a mysql driver we use here at work, and I wanted to be able to use it in our systems without having to actually use the driver (it's under development as well, and it's just easier to make changes inside that layer than to implement changes throughout an entire system). anyway, I was writing a collections object which gave access to the data returned from the querry, and this is where I though of this post and the indexing issue. I'd never really used it before then.
recently though I was writing a settings layer for another system which used the same setup you were describing here. it had to be small and use little resources and needed to be accessed like clowns["withRedHat"] = value; and string blueHat = clowns["withBlueHat"]; I had some trouble at first with the way I had implemented it because I wanted to use an int and string, but found that whatever object I used as the indexer had to match up with the key value in my hashtable, so if the hash had 1=>value1 I had to index the class Clowns[1] and if it was "withRedHat"=>value2 I had to index it as I mentioned above.
I guess it all depends on what you want to do and what your constraints are.

up0down
link

Very interesting. It could be that my original code was working all along, but not the way I expected it to. So by saying ClownCar[1] = "blah", checking for changes in what I thought was the second item in the collection may have been a bad assumption...

up0down
link

also the way you were setting it might not work either, unless the hash key value had been set before it was given a value. so the set operation might look like this.
set
{
if(this.m_tables.ContainsKey(index))
this.Clowns[index] = value;
else
this.Clowns.Add(index, value);
}

up0down
link

Hmm, I'm pretty sure I was using the Add(x,y) method;

up0down
link

I think i remember hearing/reading that items placed in the hash table don't follow a chronological numeric order, which is why it's such a fast data structure to deal with.
personally I havent used it enough to know, but it's one of the considerations I took in when writing mine, and why I used an object index instead of doing an int/string combo.

This post was imported from csharpfriends, if you have a similiar question please ask it again.

All previous members have been migrated, hope you enjoy the new platform!

Feedback