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:
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开发者_JAVA技巧# 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.
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
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.
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
)
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)
精彩评论