Создать индексатор в 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)