Indexers and Item()

J

Jeremy McPeak

I am writing a collection. I downloaded the Rotor kit and started looking at
how the classes in System.Xml are written and am using them as a guide. For
my collection, I thought I'd use XmlNodeList as my pattern.

Two particular things stand out:

public abstract XmlNode Item(int i);

and

public virtual XmlNode this [int index] {}

I created an indexer in my collection class without a problem. When I added
an Item() method to it, however, I was told that Item was already in use.
The debugger pointed to the indexer as the culprit. The compiler will not
continue.

So my question is this: How can I use an indexer and an Item() method in the
same class?

Thanks!
 
J

Jeremy McPeak

I guess I should also note that commenting out either the Item() method or
the indexer results in a successful compile.
 
N

Nicholas Paldino [.NET/C# MVP]

Jeremy,

By default, the indexer of a class will be represented as an Item method
with the same parameter list and return type. If you look at the IL for an
indexer (represented here with an int parameter and an int return type), you
will see that it is represented as a property with the name "Item":

.property int32 Item
{
.get instance int32
ConsoleApplication79.Program::get_Item(int32)
}


Also, you will notice there is an attribute on the class level:

.custom instance void
[mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = (
string("Item") )

This indicates that the Item property is the default member (indexer).

Now, if you want to have an Item method, and an indexer, then you have
to attribute the indexer with the IndexerName attribute (located in the
System.Runtime.CompilerServices namespace), indicating what name you want
your indexer to have.

However, one has to ask why you would do this, since it seems you are
doing the same thing as the indexer, so why not just let the indexer do what
it does?

Hope this helps.
 
J

Jeremy McPeak

Thanks, Nicholas. That certainly makes sense.

"However, one has to ask why you would do this, since it seems you are doing
the same thing as the indexer, so why not just let the indexer do what it
does?"

My understanding is that indexers are a feature of the C# language.
Therefore, if someone used my library while developing an application in
VB.NET, they couldn't use the indexer. Providing an Item() method would
enable them the functionality. Of course, I could be completely wrong (and
it certainly would be nice to know if I am!).


Nicholas Paldino said:
Jeremy,

By default, the indexer of a class will be represented as an Item
method with the same parameter list and return type. If you look at the
IL for an indexer (represented here with an int parameter and an int
return type), you will see that it is represented as a property with the
name "Item":

.property int32 Item
{
.get instance int32
ConsoleApplication79.Program::get_Item(int32)
}


Also, you will notice there is an attribute on the class level:

.custom instance void
[mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = (
string("Item") )

This indicates that the Item property is the default member (indexer).

Now, if you want to have an Item method, and an indexer, then you have
to attribute the indexer with the IndexerName attribute (located in the
System.Runtime.CompilerServices namespace), indicating what name you want
your indexer to have.

However, one has to ask why you would do this, since it seems you are
doing the same thing as the indexer, so why not just let the indexer do
what it does?

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Jeremy McPeak said:
I am writing a collection. I downloaded the Rotor kit and started looking
at how the classes in System.Xml are written and am using them as a guide.
For my collection, I thought I'd use XmlNodeList as my pattern.

Two particular things stand out:

public abstract XmlNode Item(int i);

and

public virtual XmlNode this [int index] {}

I created an indexer in my collection class without a problem. When I
added an Item() method to it, however, I was told that Item was already
in use. The debugger pointed to the indexer as the culprit. The compiler
will not continue.

So my question is this: How can I use an indexer and an Item() method in
the same class?

Thanks!
 
N

Nicholas Paldino [.NET/C# MVP]

Jeremy,

Well, have you tried to use your class from VB.NET? You will find that
the Item property should be there already. =)

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Jeremy McPeak said:
Thanks, Nicholas. That certainly makes sense.

"However, one has to ask why you would do this, since it seems you are
doing the same thing as the indexer, so why not just let the indexer do
what it does?"

My understanding is that indexers are a feature of the C# language.
Therefore, if someone used my library while developing an application in
VB.NET, they couldn't use the indexer. Providing an Item() method would
enable them the functionality. Of course, I could be completely wrong (and
it certainly would be nice to know if I am!).


Nicholas Paldino said:
Jeremy,

By default, the indexer of a class will be represented as an Item
method with the same parameter list and return type. If you look at the
IL for an indexer (represented here with an int parameter and an int
return type), you will see that it is represented as a property with the
name "Item":

.property int32 Item
{
.get instance int32
ConsoleApplication79.Program::get_Item(int32)
}


Also, you will notice there is an attribute on the class level:

.custom instance void
[mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = (
string("Item") )

This indicates that the Item property is the default member (indexer).

Now, if you want to have an Item method, and an indexer, then you have
to attribute the indexer with the IndexerName attribute (located in the
System.Runtime.CompilerServices namespace), indicating what name you want
your indexer to have.

However, one has to ask why you would do this, since it seems you are
doing the same thing as the indexer, so why not just let the indexer do
what it does?

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Jeremy McPeak said:
I am writing a collection. I downloaded the Rotor kit and started looking
at how the classes in System.Xml are written and am using them as a
guide. For my collection, I thought I'd use XmlNodeList as my pattern.

Two particular things stand out:

public abstract XmlNode Item(int i);

and

public virtual XmlNode this [int index] {}

I created an indexer in my collection class without a problem. When I
added an Item() method to it, however, I was told that Item was already
in use. The debugger pointed to the indexer as the culprit. The compiler
will not continue.

So my question is this: How can I use an indexer and an Item() method in
the same class?

Thanks!
 
J

Jeremy McPeak

Sweet! Thanks a bunch, Nicholas!


Nicholas Paldino said:
Jeremy,

Well, have you tried to use your class from VB.NET? You will find that
the Item property should be there already. =)

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Jeremy McPeak said:
Thanks, Nicholas. That certainly makes sense.

"However, one has to ask why you would do this, since it seems you are
doing the same thing as the indexer, so why not just let the indexer do
what it does?"

My understanding is that indexers are a feature of the C# language.
Therefore, if someone used my library while developing an application in
VB.NET, they couldn't use the indexer. Providing an Item() method would
enable them the functionality. Of course, I could be completely wrong
(and it certainly would be nice to know if I am!).


Nicholas Paldino said:
Jeremy,

By default, the indexer of a class will be represented as an Item
method with the same parameter list and return type. If you look at the
IL for an indexer (represented here with an int parameter and an int
return type), you will see that it is represented as a property with the
name "Item":

.property int32 Item
{
.get instance int32
ConsoleApplication79.Program::get_Item(int32)
}


Also, you will notice there is an attribute on the class level:

.custom instance void
[mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = (
string("Item") )

This indicates that the Item property is the default member
(indexer).

Now, if you want to have an Item method, and an indexer, then you
have to attribute the indexer with the IndexerName attribute (located in
the System.Runtime.CompilerServices namespace), indicating what name you
want your indexer to have.

However, one has to ask why you would do this, since it seems you are
doing the same thing as the indexer, so why not just let the indexer do
what it does?

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


I am writing a collection. I downloaded the Rotor kit and started
looking at how the classes in System.Xml are written and am using them
as a guide. For my collection, I thought I'd use XmlNodeList as my
pattern.

Two particular things stand out:

public abstract XmlNode Item(int i);

and

public virtual XmlNode this [int index] {}

I created an indexer in my collection class without a problem. When I
added an Item() method to it, however, I was told that Item was already
in use. The debugger pointed to the indexer as the culprit. The
compiler will not continue.

So my question is this: How can I use an indexer and an Item() method
in the same class?

Thanks!
 

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

Similar Threads


Top