C# 名为“索引器”;项目「;接口要求但不可能实现?
我试图在ESPRIT api中实现一个类的接口,该接口需要一个名为“Item”的索引器。(我猜该接口来自VB.NET,但我没有源代码。)显然,“Item[index]”索引器默认由编译器自动生成,但我得到以下错误: 我意识到C# 名为“索引器”;项目「;接口要求但不可能实现?,c#,.net,vb.net,interface,indexer,C#,.net,Vb.net,Interface,Indexer,我试图在ESPRIT api中实现一个类的接口,该接口需要一个名为“Item”的索引器。(我猜该接口来自VB.NET,但我没有源代码。)显然,“Item[index]”索引器默认由编译器自动生成,但我得到以下错误: 我意识到[System.Runtime.CompilerServices.IndexerName(“Item”)]是冗余的;它只是为了明确地证明生成了项,错误仍然存在 试图实现公共工具栏控件项[int index]“splodes类其余部分中的所有内容 编辑1:第三个屏幕截图显示了
[System.Runtime.CompilerServices.IndexerName(“Item”)]
是冗余的;它只是为了明确地证明生成了项
,错误仍然存在
试图实现公共工具栏控件项[int index]
“splodes类其余部分中的所有内容
编辑1:第三个屏幕截图显示了IToolBar。这是但我确实尝试了IToolBar.Item
,结果如上所述
看起来我不是第一个请求命名迭代器的人,但我认为生成的命名索引器应该满足要求。
如何实现此索引器以满足接口要求
注意:为了完整性、将来的故障排除以及回答评论中提出的问题,我正在进行以下编辑,但我已经知道,这个特定实例的解决方案是按照公认答案中的说明实施get\u Item(int index)
Edit2:要回答“visual studio建议了什么?”您可以看到,它在进行替换之前就知道,索引
将出错,因为在项
上没有定义索引
参数(我已经测试过了,它确实失败了)。自动实现的其他两个选项都不起作用。
Edit3:在对象浏览器中,在IToolBar
内部,项[int]
被定义为:问题是没有有效的C语法来声明命名索引器,因此无法使用C满足该接口。有几项要求在C语言中实现命名索引器的请求都被C语言团队忽略或直接拒绝。他们似乎不想在C#中实现此功能。也许如果他们以后改变主意,你可能会有机会
目前,我唯一能想到的方法是创建一个VB.NET库,其中包含一个类,该类实现接口,并充当您自己类的包装器或基类。C#可以满足这一要求。使用get\u Item
接口的项“indexer”。这是因为在IL编译期间如何生成属性/索引getter和setter
以下是在中的描述:
I.10.4命名模式
对于属性:
通过确定其getter方法和
getter参数的类型(若有)然后,创建两个基于
属性名称和这些类型。对于下面的示例,我们定义了两个属性:名称
不接受任何参数并返回System.String,而项接受System.Object参数
并返回一个System.Object。项被称为索引属性,这意味着它需要
参数,因此用户可以将其视为带有索引的数组
为了进行测试,您可以在VB.NET中创建一个简单的界面:
Public Interface IVBNetInterface
Property Item(index As Integer) As String
End Interface
然后在C#中的一个新类上实现该接口。请注意,当允许IDE自动实现接口时,它是如何默认为get\u Item/set\u Item
访问器的:
public class CSharpClass : IVBNetInterface
{
public string get_Item(int index)
{
throw new NotImplementedException();
}
public void set_Item(int index, string Value)
{
throw new NotImplementedException();
}
}
读取接口的生成IL可确认此行为:
那么VB.NET的默认属性呢?
在VB.NET中,有一个Default
property decorator,它本质上是在类上声明索引器的机制:
Public Interface IVBNetInterface
Default Property Item(index As Integer) As String
End Interface
当这在VB.NET类/接口上正确实现时,标准的C#此[int]
索引实现将起作用。因此,只有当默认属性未正确应用于目标索引属性时,get\u项
解决方法才真正有必要。请注意,在应用IL代码后调查IL代码时,添加了System.Reflection.DefaultMemberAttribute
属性:
提高使用率:
要绕过未使用Default
修饰符编写的底层类/接口,可以明确地实现接口索引器,这允许在类上公开传统的C风格索引器:
public class CSharpClass : IVBNetInterface
{
public string this[int index]
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
#region IVBNetInterface
string IVBNetInterface.get_Item(int index) => this[index];
void IVBNetInterface.set_Item(int index, string value) => this[index] = value;
#endregion
}
如果您希望通过典型索引器推断类的用法,同时仍满足底层接口项要求,则这可能是首选方法。是否有用于您正在使用的自定义库的API文档?删除您自己的代码后,当您将鼠标悬停在Esprit.Tooolbar上时,Visual Studio建议实现什么?此缺少的成员的接口规范是什么?是否确定this[]
的返回类型为“ToolBarControl”?如果找不到文档,请在反汇编程序中打开引用,查看它具体在查找什么@Neil可能是对的,它可能需要来自索引器的“object”或“IToolbarControl”。我实现了get_Item
aspublic ToolBarControl get_Item(int index)=>ToolBar.Item[index]
和它(奇怪的是)满足了项[int]get
要求。想在答案顶部添加一个TLDR简介,基本上说明get_Item(int index)
可以满足接口的Item
要求吗?@Still.Tony,我与另一个用VB.NET编写的第三方库合作过,我注意到了一些类似的行为。如果您有一个IL反汇编程序,那么可能值得查看IToolbar以查看底层代码。也许在某个地方用“Esprit”更新您的问题,以便其他人能够找到。
Public Interface IVBNetInterface
Default Property Item(index As Integer) As String
End Interface
public class CSharpClass : IVBNetInterface
{
public string this[int index]
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
#region IVBNetInterface
string IVBNetInterface.get_Item(int index) => this[index];
void IVBNetInterface.set_Item(int index, string value) => this[index] = value;
#endregion
}