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

发布于 2024-11-06 20:28:46 字数 717 浏览 0 评论 0原文

我可以在 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;

这就是我想要实现的目标。

Can I create a class in VB.NET which can be used from C# like that:

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:

I was trying to make it like that, but C# told me I cannot call this directly:

   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

myObject.get_Objects(index).Prop = 1234

but not

myObject.Objects[index].Prop = 1234;

this is what I want to achieve.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半暖夏伤 2024-11-13 20:28:46

语法是:

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

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. Unfortunately C# does not support named indexers. 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:

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
红墙和绿瓦 2024-11-13 20:28:46

您可以使用带有默认索引器的结构在 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];
}

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

You can fake named indexers in C# using a struct with a default indexer:

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.

流年已逝 2024-11-13 20:28:46

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

C# doesn't support the declaration of named indexed properties (although you can create indexers), but you can access indexed properties declared in other languages (like VB) by calling the setter or getter explicitly (get_MyProperty/set_MyProperty)

雪若未夕 2024-11-13 20:28:46

为什么不使用基于 0 的索引,而是给编码人员一种它是基于 1 的错觉?

IE

Return parrObjectData(index-1)

Why not make use of the 0 based indexing but give the illusion to the coder that it is 1 based?

ie

Return parrObjectData(index-1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文