C# 在VB.NET中创建可从C使用的索引器#
我可以在VB.NET中创建一个类,该类可以从C#中使用,如下所示:C# 在VB.NET中创建可从C使用的索引器#,c#,.net,vb.net,indexer,language-interoperability,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
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_对象(索引).Prop=1234
但不是
myObject.Objects[index].Prop=1234代码>
这就是我想要实现的。为什么不使用基于0的索引,但给编码器一个基于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#不支持命名索引属性的声明(尽管您可以创建索引器),但您可以通过显式调用setter或getter来访问以其他语言(如VB)声明的索引属性(get_MyProperty
/set_MyProperty
)您可以使用带有默认索引器的结构在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];
}
公共类ObjectData
{
}
公共类MyClass
{
私有列表_objects=新列表();
public ObjectsIndexer对象{get{返回新的ObjectsIndexer(this);}
公共结构对象索引
{
私有MyClass_实例;
内部ObjectsIndex(MyClass实例)
{
_实例=实例;
}
公共对象数据此[int索引]
{
得到
{
返回_实例._对象[index-1];
}
}
}
}
void Main()
{
MyClass cls=新的MyClass();
ObjectData data=cls.Objects[1];
}
如果这是一个好主意,则是另一个问题。方法签名应该是什么样子?与它一样,这应该是唯一应该更改的行。除了删除(index=0)if语句块之外,我的问题是,对于当前的方法签名,VB.NET不允许我像myObject一样调用该方法。Objects[index]Default
是您缺少的关键字。Brian的回答让你明白了。你要求的是一个索引属性,这是C#中无法直接使用的功能。如果我希望该属性有一个除Item之外的名称,你忘记了“property”关键字。需要注意的是,只有当ObjectData对象是类时,这才是一个好的解决方案。如果它是一个结构,您将无法在ObjectsIndex中存储对它的引用(最多您可以获得一个副本)。这使得使用此模式用固定缓冲区包装不安全的结构成为问题,因为不能在类中使用固定缓冲区,也不能让ObjectsIndex指向结构。
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];
}