在VB.NET中创建可以在C#中使用的索引器

时间:2011-05-13 12:44:16

标签: c# .net vb.net indexer language-interoperability

我可以在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 个答案:

答案 0 :(得分:13)

语法为:

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

答案 1 :(得分: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];
}

如果这是个好主意,那就是另一个问题。

答案 2 :(得分:1)

C#不支持命名索引属性的声明(尽管您可以创建索引器),但是您可以通过显式调用setter或getter来访问在其他语言(如VB)中声明的索引属性(get_MyProperty / set_MyProperty

答案 3 :(得分:0)

为什么不使用基于0的索引,但是给编码器假设它是1?

Return parrObjectData(index-1)