Создать индексатор в VB.NET, который можно использовать из C#

Могу ли я создать класс в VB.NET, который можно использовать из C# следующим образом:

myObject.Objects[index].Prop = 1234;

Конечно, я мог бы создать свойство, которое возвращает массив. Но требуется, чтобы индекс основывался на 1, а не на 0, поэтому этот метод должен каким-то образом отображать индексы:

Я пытался сделать это так, но C# сказал мне, что я не могу назвать это напрямую:

   Public ReadOnly Property Objects(ByVal index As Integer) As ObjectData
        Get
            If (index = 0) Then
                Throw New ArgumentOutOfRangeException()
            End If
            Return parrObjectData(index)
        End Get
    End Property

РЕДАКТИРОВАТЬ Извините, если мне было немного неясно:

C# позволяет мне только вызвать этот метод, как

myObject.get_Objects(index).Prop = 1234

но нет

myObject.Objects[index].Prop = 1234;

это то, чего я хочу достичь.

4 ответа

Решение

Вы можете подделать именованные индексаторы в C#, используя структуру с индексатором по умолчанию:

public class ObjectData
{
}

public class MyClass
{
    private List<ObjectData> _objects=new List<ObjectData>();
    public ObjectsIndexer Objects{get{return new ObjectsIndexer(this);}}

    public struct ObjectsIndexer
    {
        private MyClass _instance;

        internal ObjectsIndexer(MyClass instance)
        {
            _instance=instance;
        }

        public ObjectData this[int index]
        {
            get
            {
                return _instance._objects[index-1];
            }
        }
    }
}

void Main()
{
        MyClass cls=new MyClass();
        ObjectData data=cls.Objects[1];
}

Если это хорошая идея, это другой вопрос.

Синтаксис:

Default Public ReadOnly Property Item(ByVal index as Integer) As ObjectData
  Get
    If (index = 0) Then
      Throw New ArgumentOutOfRangeException()
    End If
    Return parrObjectData(index)
  End Get
End Property

Default Ключевое слово - это магия, которая создает индексатор. К сожалению, C# не поддерживает именованные индексаторы. Вам нужно будет создать пользовательскую оболочку коллекции и вернуть ее.

Public ReadOnly Property Objects As ICollection(Of ObjectData)
  Get
    Return New CollectionWrapper(parrObjectData)
  End Get
End Property

Где CollectionWrapper может выглядеть так:

Private Class CollectionWrapper
  Implements ICollection(Of ObjectData)

  Private m_Collection As ICollection(Of ObjectData)

  Public Sub New(ByVal collection As ICollection(Of ObjectData))
    m_Collection = collection
  End Sub

  Default Public ReadOnly Property Item(ByVal index as Integer) As ObjectData
    Get
      If (index = 0) Then
        Throw New ArgumentOutOfRangeException()
      End If
      Return m_Collection(index)
    End Get
  End Property

End Class

C# не поддерживает объявление именованных индексированных свойств (хотя вы можете создавать индексаторы), но вы можете получить доступ к индексированным свойствам, объявленным в других языках (например, VB), явно вызвав метод set или getter (get_MyProperty/set_MyProperty)

Почему бы не использовать индексирование на основе 0, но дать иллюзию кодеру, что он основан на 1?

т.е.

Return parrObjectData(index-1)
Другие вопросы по тегам