C# может удовлетворить этот «индексатор» .Item из интерфейса с get_Item
. Это связано с тем, как во время компиляции IL генерируются геттеры и установщики свойств/индексов.
Вот как это описано в спецификации CLI а>:
I.10.4 Шаблоны именования
Для свойств:
Отдельное свойство создается путем выбора типа, возвращаемого его методом получения, и типов параметров получателя (если они есть). Затем создаются два метода с именами, основанными на имени свойства и этих типах. В приведенных ниже примерах мы определяем два свойства: Имя не принимает параметров и возвращает значение System. .String, а Item принимает параметр System.Object и возвращает System.Object. Элемент называется индексированным свойством, что означает, что он принимает параметры и, таким образом, может отображаться для пользователя как массив с индексами.
PropertyGet, used to read the value of the property
Pattern: <PropType> get_<PropName> (<Indices>)
Example: System.String get_Name ();
Example: System.Object get_Item (System.Object key);
PropertySet, used to modify the value of the property
Pattern: void set_<PropName> (<Indices>, <PropType>)
Example: void set_Name (System.String name);
Example: void set_Item (System.Object key, System.Object value);
Поэтому вы должны быть в состоянии выполнить условия реализации индексатора примерно так:
public class ManagedEspritToolbar : Esprit.Toolbar
{
public ToolbarControl get_Item(int index) => Toolbar[index];
}
Для проверки этого вы можете создать простой интерфейс в VB.NET:
Public Interface IVBNetInterface
Property Item(index As Integer) As String
End Interface
Затем реализуйте интерфейс в новом классе на C#. Обратите внимание, что по умолчанию используется get_Item/set_Item
средств доступа, когда среда IDE может автоматически реализовывать интерфейс:
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
, который, по сути, является механизмом объявления индексатора в классе:
Public Interface IVBNetInterface
Default Property Item(index As Integer) As String
End Interface
Когда это правильно реализовано в классе/интерфейсе VB.NET, стандартная реализация индексации C# this[int]
будет работать. Поэтому обходной путь get_Item
должен быть действительно необходим только тогда, когда атрибут по умолчанию не правильно применен к свойству целевого индекса. Обратите внимание на добавление атрибута System.Reflection.DefaultMemberAttribute
при исследовании кода IL после его применения:

Улучшение использования:
Чтобы обойти базовые классы/интерфейсы, не написанные с модификатором 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
}
Это может быть предпочтительным подходом, если вы хотите, чтобы использование класса выводилось с помощью типичного индексатора, при этом удовлетворяя базовому требованию Interface.Item.
23.08.2018
get_Item
какpublic ToolBarControl get_Item(int index) => ToolBar.Item[index];
, и это (как ни странно) удовлетворило требованиюItem[int] get
. Хотите добавить аннотацию TLDR в верхней части вашего ответа, в которой говорится, чтоget_Item(int index)
может удовлетворить требованиеItem
к интерфейсу? 24.08.2018