Не целочисленные индексированные свойства индексатора в C#

Я хочу иметь индексированное свойство в 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 жалуется на синтаксис нецелого индекса:

я знаю .NET поддерживает нецелые индексы.


На другом языке я бы написал:

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;

5 ответов

Решение

Ваш синтаксис неверен:

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

Индексаторы объявляются с использованием this ключевое слово - вы не можете использовать свое собственное имя.

Из использования индексаторов (Руководство по программированию в C#):

Чтобы объявить индексатор для класса или структуры, используйте ключевое слово this


Кроме того, возможно иметь только один индексатор, который принимает тип - это ограничение синтаксиса индексатора C# (может быть ограничение IL, не уверен).

Индексаторы работают только с this ключевое слово. Смотрите здесь.

Это ключевое слово используется для определения индексаторов.

Как сказали Мэтт Берланд и Одед, индексаторы работают только с этим ключевым словом, поэтому вам нужен прокси-класс с нужным вам интерфейсом:

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

    ...
}

На самом деле вы можете иметь несколько индексаторов, принимающих типы.

Однако вы не можете иметь два индексатора с одинаковой подписью. Одна и та же подпись означает номер и тип параметра - поэтому в приведенном выше коде есть два индексатора с одинаковой подписью.

Если код изменился на:

    Boolean this[string x, Guid personguid]

а также:

    Boolean this[Guid personguid]

он должен работать.

@Jojan ответил здесь:

C# 3.0 spec

"Перегрузка индексаторов позволяет классу, структуре или интерфейсу объявлять несколько индексаторов при условии, что их сигнатуры уникальны в этом классе, структуре или интерфейсе".

или если ваш набор данных небольшой, вы можете IList

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

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

или используйте метод множественных индексаторов с использованием интерфейсов

Другие вопросы по тегам