Можно ли разрешить только некоторым определенным классам реализовать итерал?
Скажем, что я создал интерфейс IMyInterface
, и я хочу, чтобы только классы, полученные из UserControl
, имели возможность реализовать мой интерфейс. Возможно ли это?
Разрешить реализацию интерфейса только для определенных классов
Ответ 1
Вы не можете, но вы можете добиться чего-то подобного, добавив свойство Control в свой интерфейс, и по-соглашения, делая все реализации return this
. Не решает вашу проблему, но делает реализованную ситуацию немного погодной, поэтому интерфейс действительно здесь. Также позволяет пользователю интерфейса получать элемент управления безопасным способом без кастования.
interface IMyInterface
{
void Foo();
UserControl Control { get; }
}
class MyControl : UserControl, IMyInterface
{
public void Foo()
{
// TODO: Write code here
}
UserControl IMyInterface.Control
{
get { return this; }
}
}
UPDATE
Существует и другое решение - создание общего метода. Сам интерфейс не будет ограничен, но будет работать метод. Например, следующий метод требует, чтобы его параметр наследовал UserControl
и реализовал IMyInterface
:
void Bar<T>(T item)
where T : UserControl, IMyInterface
{
item.Width = 120; // user control property
item.Foo(); // IMyInterface method
}
Ответ 2
Похоже, вы хотите что-то вроде этого:
abstract class IMyInterface : UserControl { }
Конечно, IMyInterface
больше не является подходящим именем, но любой класс, полученный из IMyInterface
, также выводится из UserControl
, который удовлетворяет вашим требованиям.
Ответ 3
Я понимаю, что это старый пост, но мне пришлось решить именно эту проблему.
Вот как вы можете это сделать:
class BaseClass { }
interface OnlyBaseClass<TSelf> where TSelf : BaseClass, OnlyBaseClass<TSelf>
{
}
class ChildClass : BaseClass, OnlyBaseClass<ChildClass> { }
class ImpostorClass : OnlyBaseClass<ImposterClass> { }
interface ImposterInterface : OnlyBaseClass<ImposterInterface > { }
Попробуйте собрать выше. Вы заметите, что он не компилируется (из-за двух самозванцев, одного класса, одного интерфейса).
Ограничение на TSelf можно понимать как:
TSelf должен: Наследовать от BaseClass и реализовать OnlyBaseClass <TSelf>
... который может использовать только тип, наследующий BaseClass и реализующий OnlyBaseClass.
Вы можете быть умными и делать следующее:
class AdvancedImpostorClass : OnlyBaseClass<ChildClass> {}
... который будет компилироваться. Вы можете помешать этим типам самозванцев проникать в ваш код, используя те же ограничения в любых методах, которые принимают их как аргументы, например:
public SomeMethod<TBaseAndInterface>(TBaseAndInterface value)
where TBaseAndInterface: BaseClass, OnlyBaseClass<TBaseAndInterface>
{ }
Все это стало возможным благодаря силе F-Bound Polymorphism.
Ответ 4
Это невозможно. Если вы видите интерфейс, его можно реализовать.
Ответ 5
Нет, нет способа ограничить реализацию интерфейса конкретными типами. Зачем вам это нужно? Почему потребитель абстракции заботится о конкретных типах, реализующих этот контракт? Каков ваш прецедент?
Ответ 6
Случай, который вы описываете, по-видимому, соответствует "абстрактному методу в родительском классе" (здесь userControl), если интерфейс уже не существует для других целей.
Без тела по умолчанию деривативные классы должны будут обеспечивать поведение.