2

I want to have an indexed property in C#:

public Boolean IsSelected[Guid personGuid]
{
   get {
      Person person = GetPersonByGuid(personGuid);
      return person.IsSelected;
   }
   set {
      Person person = GetPersonByGuid(personGuid);
      person.IsSelected = value;
   }
}
public Boolean IsApproved[Guid personGuid]
{
   get {
      Person person = GetPersonByGuid(personGuid);
      return person.IsApproved;
   }
   set {
      Person person = GetPersonByGuid(personGuid);
      person.IsApproved= value;
   }
}

Visual Studio complains on the non-integer indexer syntax:

i know .NET supports non-Integer indexors.


In another language i would write:

private
   function GetIsSelected(ApproverGUID: TGUID): Boolean;
   procedure SetIsSelected(ApproverGUID: TGUID; Value: Boolean);
   function GetIsApproved(ApproverGUID: TGUID): Boolean;
   procedure SetIsApproved(ApproverGUID: TGUID; Value: Boolean);
public
   property IsSelected[ApproverGuid: TGUID]:Boolean read GetIsSelected write SetIsSelected;
   property IsApproved[ApproverGuid: TGUID]:Boolean read GetIsApproved write SetIsApproved;
end;
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219

5 Answers5

7

Your syntax is incorrect:

public Boolean this[Guid personGuid]
{
   get {
      Person person = GetPersonByGuid(personGuid);
      return person.IsSelected;
   }
   set {
      Person person = GetPersonByGuid(personGuid);
      person.IsSelected = value;
   }
}

Indexers are declared using the this keyword - you can't use your own name.

From Using Indexers (C# Programming Guide):

To declare an indexer on a class or struct, use the this keyword


Additionally, it is only possible to have one indexer that accepts a type - this is a limitation of the indexer syntax of C# (might be an IL limitation, not sure).

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • That would mean that i can't have two (e.g. `IsSelected[Guid personGuid]` and `IsApproved[Guid personGuid]`) indexed properties? – Ian Boyd Oct 10 '12 at 18:03
  • @IanBoyd - True. One limitation of indexers. Though you could have an `IsApproved[string reallyAGUID]` and parse into a GUID (ugly hack, but you see where I am going). – Oded Oct 10 '12 at 18:05
  • @IanBoyd: Correct. You can have multiple indexors if they have different types of keys, but you can't have indexes work how you want them to. You'd be better off with a `ToggleSelected(Guid personGuid)` and an `ToggleApproval(Guid personGuid)` methods, or something similar. – Matt Burland Oct 10 '12 at 18:05
  • Update your answer with *"cannot do - limitation of indexers"* and i'll accept it. – Ian Boyd Oct 10 '12 at 18:06
5

Indexers only work with the this keyword. See here.

The this keyword is used to define the indexers.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
1

Just like Matt Burland and Oded said, indexers only work with this keyword, so you need to have a proxy class with the interface you need:

public class PersonSelector
{
    private MyClass owner;

    public PersonSelector(MyClass owner)
    {
        this.owner = owner;
    }

    public bool this[Guid personGuid]
    {
       get {
          Person person = owner.GetPersonByGuid(personGuid);
          return person.IsSelected;
       }
       set {
          Person person = owner.GetPersonByGuid(personGuid);
          person.IsSelected = value;
       }
    }

}

public class MyClass
{
    public MyClass()
    {
        this.IsSelected = new PersonSelector(this);
    }   

    public PersonSelector IsSelected { get; private set; }

    ...
}
zahir
  • 1,298
  • 2
  • 15
  • 35
0

@Jojan answered here:

C# 3.0 spec

"Overloading of indexers permits a class, struct, or interface to declare multiple indexers, provided their signatures are unique within that class, struct, or interface."

or if your data set is small you can IList

public IList<Boolean> IsSelected
{
   get { ... }
}

public IList<Boolean> IsApproved
{
   get { .... }
}

or use Multiple Indexers technique using Interfaces

Community
  • 1
  • 1
Mohsen Afshin
  • 13,273
  • 10
  • 65
  • 90
0

Actually you can have multiple indexers accepting types.

However you can not have two indexers with the same signature. Same signature means the parameter number and types - so the above code has two indexers with same signature.

If the code changed to :

    Boolean this[string x, Guid personguid]

and :

    Boolean this[Guid personguid]

it should work.

Andrii Kalytiiuk
  • 1,501
  • 14
  • 26
wade
  • 1