简体   繁体   English

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

[英]Create Indexer in VB.NET which can be used from C#

Can I create a class in VB.NET which can be used from C# like that: 我可以在VB.NET中创建一个可以在C#中使用的类:

myObject.Objects[index].Prop = 1234;

Sure I could create a property which returns an array. 当然我可以创建一个返回数组的属性。 But the requirement is that the index is 1-based, not 0-based, so this method has to map the indices somehow: 但要求是索引是从1开始的,而不是从0开始的,所以这个方法必须以某种方式映射索引:

I was trying to make it like that, but C# told me I cannot call this directly: 我试图这样做,但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

EDIT Sorry if I was a bit unclear: 编辑对不起,如果我有点不清楚:

C# only allows my to call this method like C#只允许我调用这个方法

myObject.get_Objects(index).Prop = 1234

but not 但不是

myObject.Objects[index].Prop = 1234;

this is what I want to achieve. 这就是我想要实现的目标。

The syntax is: 语法是:

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

The Default keyword is the magic that creates the indexer. Default关键字是创建索引器的魔力。 Unfortunately C# does not support named indexers. 不幸的是,C#不支持命名索引器。 You are going to have to create a custom collection wrapper and return that instead. 您将不得不创建一个自定义集合包装并返回它。

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

Where the CollectionWrapper might would look like this: 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

You can fake named indexers in C# using a struct with a default indexer: 您可以使用带有默认索引器的结构在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];
}

If that's a good idea is a different question. 如果这是一个好主意是一个不同的问题。

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

Why not make use of the 0 based indexing but give the illusion to the coder that it is 1 based? 为什么不使用基于0的索引,但给编码器假设它是基于1?

ie

Return parrObjectData(index-1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM