Question

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;
Était-ce utile?

La solution

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).

Autres conseils

Indexers only work with the this keyword. See here.

The this keyword is used to define the indexers.

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; }

    ...
}

@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

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top