String parameter indexer question.

S

SpotNet

Hello NewsGroup,

I have a custom class and a collection for that custom class that inherits
CollectionBase. As such;

public class MyClass
{
private string datamember1 = string.Empty, datamember2 = string.Empty;
private int datamember3 = -1;

public MyClass(string dataMember1) {this.datamember1 = dataMember1;}

public void AGreatFunction() {//The usual stuff}

public bool TrueOrFalse(string argument) {return false;}

public string DataMember1
{get {return this.datamember1;}
}//public class MyClass

public class MyClassCollection: CollectionBase
{
public MyClass this[int index] //How well this works
{
set {this.List[index] = value;}
get {return (MyClass) this.List[Index];}
}

public MyClass this[string classKey] //This doesn't work
{
set {this.List[this.List.IndexOf(classKey)] = value;}
get {return (MyClass) this.List[this.List.IndexOf(classKey)];}
}
}//public class MyClassCollection: CollectionBase

This string indexer doesn't work as 'this.List.IndexOf(classKey)' always
returns -1. Can someone tell me please what I must consider to get a string
indexer working for this situation? Many thanks news group.

Regards,
SpotNet.
 
G

Guest

CollectionBase.IndexOf( object value ) searches for 'value' as an item within
the list, whereas it appears that you're trying to search for an object that
has a property equal to 'value.'

To get the functionality you want, if I'm understanding you correctly, you
have to search the list.

public virtual MyClass this[ string dataMember1 ]
{
get
{
for ( int i = 0; i < List.Count; i++ )
{
if( this[ i ].DataMember1 == dataMember1 )
{
return this[ i ];
}
}
throw new IndexOutOfRangeException();
}
}

The linear search above is the method that the framework uses for the
ArrayList inside your CollectionBase (well, all right, the framework's
version might be cleaner, but I'm not near VS at the moment). If your list
can be sorted, more efficient methods may be available; Google "array search
algorithms."

You may also be able to derive from NameOjectCollectionBase, but that might
not offer quite the functionality you want. (In particular, since
NameObjectCollectionBase stores the key separately from the object, you would
need to implement a DataMember1Changed event in MyClass and handle it in the
collection . . . and add and remove handlers as collection items are added
and removed.)

HTH.
 
J

Jon Skeet [C# MVP]

SpotNet said:
public class MyClassCollection: CollectionBase
{
public MyClass this[int index] //How well this works
{
set {this.List[index] = value;}
get {return (MyClass) this.List[Index];}
}

public MyClass this[string classKey] //This doesn't work
{
set {this.List[this.List.IndexOf(classKey)] = value;}
get {return (MyClass) this.List[this.List.IndexOf(classKey)];}
}
}//public class MyClassCollection: CollectionBase

This string indexer doesn't work as 'this.List.IndexOf(classKey)' always
returns -1. Can someone tell me please what I must consider to get a string
indexer working for this situation? Many thanks news group.

Well, what do you expect it to do? It's currently looking for a string
in the list, and there aren't any strings in the list - just instances
of MyClass. Are you wanting it to match on DataMember1?

Unfortunately IList itself doesn't support searching with an IComparer,
which is effectively what you want to do, but you could always go
through the list manually and check each element.
 
S

SpotNet

Hello Phil N, Jon,

Thanks for the response and good advice. I didn't articulate myself all that
well, primarily I wanted (obviously) to have a string parameter indexer as
well as an integer one. I discovered the hard way what I posted didn't work,
I wanted to know if a string parameter indexer was possible using the
CollectionBase parent or base.

I've implemented your solutions (works well indeed thanks) and wanted to ask
in this situation, which would be better to use;

for (int idx = 0; idx < mycollection.Count; i++) {if
(this.DataMemeber1.Equals(paramString) {...; break;}} Or,
foreach(MyClass mc in this) {if (mc.DataMember1.Equals(paramString) {...;
break;}}....

Thanks again...

Regards,
SpotNet.
:
: Hello NewsGroup,
:
: I have a custom class and a collection for that custom class that inherits
: CollectionBase. As such;
:
: public class MyClass
: {
: private string datamember1 = string.Empty, datamember2 = string.Empty;
: private int datamember3 = -1;
:
: public MyClass(string dataMember1) {this.datamember1 = dataMember1;}
:
: public void AGreatFunction() {//The usual stuff}
:
: public bool TrueOrFalse(string argument) {return false;}
:
: public string DataMember1
: {get {return this.datamember1;}
: }//public class MyClass
:
: public class MyClassCollection: CollectionBase
: {
: public MyClass this[int index] //How well this works
: {
: set {this.List[index] = value;}
: get {return (MyClass) this.List[Index];}
: }
:
: public MyClass this[string classKey] //This doesn't work
: {
: set {this.List[this.List.IndexOf(classKey)] = value;}
: get {return (MyClass) this.List[this.List.IndexOf(classKey)];}
: }
: }//public class MyClassCollection: CollectionBase
:
: This string indexer doesn't work as 'this.List.IndexOf(classKey)' always
: returns -1. Can someone tell me please what I must consider to get a
string
: indexer working for this situation? Many thanks news group.
:
: Regards,
: SpotNet.
:
:
 
G

Guest

It depends on your application, and there's a bit of a catch 22 here.
Enumerating over the collection (using foreach) introduces heap and virtual
function overhead that isn't present with the linear search (using for), so
for will reduce the application's resource consumption as the size of the
collection increases. The catch: a linear search really begins to waste
processor cycles on large collections anyway. Think here of how much is
wasted by using a linear search to find "Zebra" in an unabridged dictionary,
for example.

If your collection might get really large, reply and say so, and I'll give
you some tips on improving the performance.

SpotNet said:
Hello Phil N, Jon,

Thanks for the response and good advice. I didn't articulate myself all that
well, primarily I wanted (obviously) to have a string parameter indexer as
well as an integer one. I discovered the hard way what I posted didn't work,
I wanted to know if a string parameter indexer was possible using the
CollectionBase parent or base.

I've implemented your solutions (works well indeed thanks) and wanted to ask
in this situation, which would be better to use;

for (int idx = 0; idx < mycollection.Count; i++) {if
(this.DataMemeber1.Equals(paramString) {...; break;}} Or,
foreach(MyClass mc in this) {if (mc.DataMember1.Equals(paramString) {...;
break;}}....

Thanks again...

Regards,
SpotNet.
:
: Hello NewsGroup,
:
: I have a custom class and a collection for that custom class that inherits
: CollectionBase. As such;
:
: public class MyClass
: {
: private string datamember1 = string.Empty, datamember2 = string.Empty;
: private int datamember3 = -1;
:
: public MyClass(string dataMember1) {this.datamember1 = dataMember1;}
:
: public void AGreatFunction() {//The usual stuff}
:
: public bool TrueOrFalse(string argument) {return false;}
:
: public string DataMember1
: {get {return this.datamember1;}
: }//public class MyClass
:
: public class MyClassCollection: CollectionBase
: {
: public MyClass this[int index] //How well this works
: {
: set {this.List[index] = value;}
: get {return (MyClass) this.List[Index];}
: }
:
: public MyClass this[string classKey] //This doesn't work
: {
: set {this.List[this.List.IndexOf(classKey)] = value;}
: get {return (MyClass) this.List[this.List.IndexOf(classKey)];}
: }
: }//public class MyClassCollection: CollectionBase
:
: This string indexer doesn't work as 'this.List.IndexOf(classKey)' always
: returns -1. Can someone tell me please what I must consider to get a
string
: indexer working for this situation? Many thanks news group.
:
: Regards,
: SpotNet.
:
:
 
S

SpotNet

Hello Phil N,

Thanks for the explanation. The collection I'm dealing with is actually
small with the remote possibility that it might be large. The reason I asked
was due to some C# literature I read comparing the 'for' with the 'foreach'
loop statements. The loops cycled through objects expressed as an object
array in the 'for' case then object enumeration using 'foreach'. The
conclusions being that when looping through objects its' best to use
foreach, then I heard otherwise which is my main reason for asking. I didn't
really think it was size (number of objects) based until now. Thank you very
much for that.

Regards,
SpotNet.

: It depends on your application, and there's a bit of a catch 22 here.
: Enumerating over the collection (using foreach) introduces heap and
virtual
: function overhead that isn't present with the linear search (using for),
so
: for will reduce the application's resource consumption as the size of the
: collection increases. The catch: a linear search really begins to waste
: processor cycles on large collections anyway. Think here of how much is
: wasted by using a linear search to find "Zebra" in an unabridged
dictionary,
: for example.
:
: If your collection might get really large, reply and say so, and I'll give
: you some tips on improving the performance.
:
: "SpotNet" wrote:
:
: >
: > Hello Phil N, Jon,
: >
: > Thanks for the response and good advice. I didn't articulate myself all
that
: > well, primarily I wanted (obviously) to have a string parameter indexer
as
: > well as an integer one. I discovered the hard way what I posted didn't
work,
: > I wanted to know if a string parameter indexer was possible using the
: > CollectionBase parent or base.
: >
: > I've implemented your solutions (works well indeed thanks) and wanted to
ask
: > in this situation, which would be better to use;
: >
: > for (int idx = 0; idx < mycollection.Count; i++) {if
: > (this.DataMemeber1.Equals(paramString) {...; break;}} Or,
: > foreach(MyClass mc in this) {if (mc.DataMember1.Equals(paramString)
{...;
: > break;}}....
: >
: > Thanks again...
: >
: > Regards,
: > SpotNet.
: > : > :
: > : Hello NewsGroup,
: > :
: > : I have a custom class and a collection for that custom class that
inherits
: > : CollectionBase. As such;
: > :
: > : public class MyClass
: > : {
: > : private string datamember1 = string.Empty, datamember2 =
string.Empty;
: > : private int datamember3 = -1;
: > :
: > : public MyClass(string dataMember1) {this.datamember1 =
dataMember1;}
: > :
: > : public void AGreatFunction() {//The usual stuff}
: > :
: > : public bool TrueOrFalse(string argument) {return false;}
: > :
: > : public string DataMember1
: > : {get {return this.datamember1;}
: > : }//public class MyClass
: > :
: > : public class MyClassCollection: CollectionBase
: > : {
: > : public MyClass this[int index] //How well this works
: > : {
: > : set {this.List[index] = value;}
: > : get {return (MyClass) this.List[Index];}
: > : }
: > :
: > : public MyClass this[string classKey] //This doesn't work
: > : {
: > : set {this.List[this.List.IndexOf(classKey)] = value;}
: > : get {return (MyClass) this.List[this.List.IndexOf(classKey)];}
: > : }
: > : }//public class MyClassCollection: CollectionBase
: > :
: > : This string indexer doesn't work as 'this.List.IndexOf(classKey)'
always
: > : returns -1. Can someone tell me please what I must consider to get a
: > string
: > : indexer working for this situation? Many thanks news group.
: > :
: > : Regards,
: > : SpotNet.
: > :
: > :
: >
: >
: >
 

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