Подобный этому вопросу о Java. Я хотел бы указать, что переменная реализует несколько интерфейсов. Например,
private {IFirstInterface, ISecondInterface} _foo;
public void SetFoo({IFirstInterface, ISecondInterface} value)
{
_foo = value;
}
Требования:
Действительно ли это возможно?
Править: Я хотел это несколько раз по различным причинам. В этом экземпляре это - потому что я изменяю ряд свойств от ObservableCollections до ReadOnlyObservableCollections. У меня есть класс помощника, который создает проекцию из источника ObservableCollection к другому Набору. Так как ReadOnlyObservableCollection не наследовался ObservableCollection, и мне только нужны операции в IList и INotifyCollectionChanged, я надеялся сохранить свой исходный набор как комбинацию этих двух интерфейсов вместо того, чтобы требовать ObservableCollection.
Если вы хотите ограничить свой метод SetFoo
, чтобы он принимал только параметры, реализующие эти два интерфейса, тогда вы в удачи:
public void SetFoo<T>(T value) where T : IFirstInterface, ISecondInterface
{
_foo = value;
}
С этого момента, когда вы захотите получить доступ к своему члену _foo
в качестве одного из этих двух интерфейсов, вам просто нужно будет получить к нему доступ через приведение типов: (IFirstInterface) _foo
или (ISecondInterface) _foo
соответственно.
Вы действительно сказали, что не хотите прибегать к приведению типов для безопасности во время компиляции; но я думаю, что если вы найдете способ гарантировать, что _foo
будет инициализирован с использованием SetFoo
выше, вы можете спокойно использовать все, что захотите.
Я только что понял, что ниже описывается то, что вы конкретно указали в вопросе, который не хотел делать. Итак, я говорю, следуйте вышесказанному.
Другая идея: поскольку похоже, что этот объект _foo
является членом класса (я основываю это предположение на _
в имени переменной), вы можете определить ваш класс таким образом:
class YourClassThatHasAFoo<T> where T : IFirstInterface, ISecondInterface {
private T _foo;
public void SetFoo(T value) {
_foo = value;
}
}
Имеет ли это смысл, очевидно, зависит от вашего конкретного сценария. Вам обязательно нужно обдумать это, поскольку классы с такими ограничениями иногда приводят к проблемам, которых вы, возможно, не ожидали в будущем (например, SetFoo
теперь должен принимать параметр типа T
, а не просто какой-либо класс, реализующий ваши два интерфейса).
Переменная в .NET имеет тип, а типы могут реализовывать несколько интерфейсов. Примерно так:
public interface Interface1 { }
public interface Interface2 { }
public class SupportsMuliple : Interface1, Interface2 { }
Но из вашего вопроса кажется, что вы хотите, чтобы переменная реализовывала несколько интерфейсов, не имея типа, который реализует эти интерфейсы. На самом деле это невозможно, но вы могли бы «на лету» сгенерировать тип, который реализует интерфейсы и скрыть тот факт, что существует настоящий тип, который творит чудеса. Библиотека имитации moq делает это с помощью Castle DynamicProxy .
Нет, невозможно декларативно гарантировать, что конкретный экземпляр реализует более одного интерфейса.
Один вариант МОЖЕТ быть возможен с использованием универсальных шаблонов, хотя на самом деле это будет работать только для функции, а не для свойства.
public void Foo<T>(T arg)
where T : IFirstInterface
where T : ISecondInterface
{
...
}
Используя вывод типа, вы должны иметь возможность вызывать его следующим образом:
ConcreteType bar = new ConcreteType(); // this implements both
Foo(bar);