Мы перемещаем интерфейсы, ранее находившиеся в VB.Net, в отдельный проект C#, который должен содержать интерфейсы, которые должны быть реализованы соответствующими классами VB.Net. Проблема возникает при попытке переместить определения интерфейса из VB.Net, которые содержат параметризованные свойства.
Я пробовал что-то вроде этого:
С#:
public interface MyInterface
{
short get_MyProperty(short parameter);
}
ВБ.Нет:
Public ReadOnly Property MyProperty(ByVal Parameter As Short) As Short
Implements CSharpProject.MyInterface.MyProperty
Get
' Do stuff
End Get
End Property
Однако ни get_MyProperty, ни MyProperty не отображаются как реализуемые методы/свойства для зависимого проекта. Перемещение параметризованных свойств в методы потребовало бы большого объема рефакторинга и было бы усилием в наихудшем сценарии. Мы ищем любые альтернативы, которые мы можем получить.
Возможный дубликат Реализация интерфейса на C# и VB.NET





Интерфейс ВБ
Interface MyInterface
ReadOnly Property MyProperty(parameter As Short) As Short
End Interface
Реализовано ВБ
Class MyVbClass
Implements MyInterface
Public ReadOnly Property MyProperty(parameter As Short) As Short _
Implements MyInterface.MyProperty
Get
End Get
End Property
End Class
и на С#
class MyCsClass : MyInterface
{
public short get_MyProperty(short parameter) { }
}
Интерфейс С#
interface MyInterface
{
short get_MyProperty(short parameter);
}
в C# реализован так же, как интерфейс VB.
class MyCsClass : MyInterface
{
public short get_MyProperty(short parameter) { }
}
а в VB реализация выглядит как C# с методом get_ и больше не является свойством только для чтения.
Class MyVbClass
Implements ClassLibrary1.MyInterface
Public Function get_MyProperty(parameter As Short) As Short _
Implements MyInterface.get_MyProperty
End Function
End Class
а так как C# не имеет параметризованных свойств, то это невозможно.
Но зачем вообще переносить интерфейсы на C#? Небольшая сборка VB.NET с интерфейсами не слишком сложна в управлении. Если вы пытаетесь уменьшить количество поставляемых сборок, это также не слишком сложно, например, с помощью ILMerge.
Эй, стоит сохранить его просто для того, чтобы показать C#, насколько хорош иногда VB.NET.
Большая часть нашего кода написана на C#, просто этот проект, над которым мы работаем, вызывает у нас проблемы. Мы стараемся больше не писать код VB.Net. Спасибо за вашу помощь!
Если вы просто беспокоитесь о том, как выглядит код (и не пытаетесь реализовать контракт), вы можете получить то, что вам нужно, разработав небольшой класс-оболочку для индексированных свойств.
class IndexedProperty<TIndexer,TValue>
{
protected readonly Func<TIndexer,TValue> _getter;
protected readonly Action<TIndexer,TValue> _setter;
public IndexedProperty(Func<TIndexer,TValue> getter, Action<TIndexer,TValue> setter)
{
_getter = getter;
_setter = setter;
}
public TValue this[TIndexer parameter]
{
get
{
return _getter(parameter);
}
set
{
_setter(parameter, value);
}
}
}
Когда у вас есть этот класс, вы можете реализовать «индексированное свойство» следующим образом:
class Foo
{
private short[] _backingStore = new short[10];
public IndexedProperty<short, short> MyProperty
{
get
{
return new IndexedProperty<short,short>
(
getter: key =>
{
//Getter logic goes here. Example:
return _backingStore[key];
},
setter: (key, val) =>
{
//Setter logic goes here. Example:
_backingStore[key] = val;
}
);
}
}
}
Теперь вы можете вызвать его привычным способом:
var foo = new Foo();
foo.MyProperty[5] = 3;
Console.WriteLine(foo.MyProperty[5]);
Выход:
3
См. мой пример на Дотнетфиддл
Примечание. Хотя все вышеперечисленное будет работать, «правильный» ответ — изменить код, чтобы использовать идиоматический С#, и забыть о том, как работал VB.NET. Это означает, что вы должны использовать методы или использовать немного другую объектную модель.
Спасибо, хотя мне просто нужен способ поддержания контракта индексированных свойств для использования VB.Net.
Увы, тогда вы облажались. См. этот вопрос для ответа Эрика Липперта о том, почему С# не поддерживает индексированные свойства.
Это невозможно в С#, поэтому я не уверен, какие «альтернативы» вам нужны. Единственное, что вы можете сделать, это преобразовать их все в методы. Я не уверен, почему вы говорите, что первый пример, который у вас есть, не отображается в зависимом проекте, хотя для меня это выглядит как допустимый метод интерфейса. Единственная другая альтернатива — оставить все в VB и вызвать его из C#.