Ответ 1
Вы можете использовать generics с ограничениями:
public interface MyClass {
public T GetMyControl() where T : Control, IMyInterface { /* ........ */ }
}
Мне нужен член моего класса для управления, а для него - интерфейс, который мы определяем.
Если я объявлю это так...
public class MyClass
{
public Control MyMember;
}
... тогда я не получаю методы интерфейса, но если я объявлю это так...
public class MyClass
{
public IMyInterface MyMember;
}
... тогда я не получаю методы управления. Есть ли способ указать, что MyMember должен быть инициализирован типом, который наследуется от обоих? Я не могу найти его на MSDN. Что-то вроде...
public class MyClass
{
public Control : IMyInterface MyMember;
}
... или...
public class MyClass
{
public Control MyMember : IMyInterface;
}
... за исключением того, что никто из них не работает. Могу ли я указать интерфейсы, когда я объявляю член, и если да, то как?
Вы можете использовать generics с ограничениями:
public interface MyClass {
public T GetMyControl() where T : Control, IMyInterface { /* ........ */ }
}
Поскольку очень сложно писать класс оболочки вокруг элемента управления и простой общий класс:
public class MyGenericClass<T> where T : Control, IMyInterface
{
public T t;
}
может не соответствовать вашим потребностям. Вы можете просто использовать разные свойства для доступа к полю по-разному:
public class MyClass
{
private IMyInterface m_field;
public Control FieldAsControl
{
get { return m_field as Control; }
}
public IMyInterface Field
{
get { return m_field; }
set
{
if (m_field is Control)
{
m_field = value;
}
else
{
throw new ArgumentException();
}
}
}
}
Вы можете создать свой собственный класс из элемента управления с помощью интерфейса, определенного следующим образом:
class MyControl : Control, IMyInterface
{
}
а затем используйте этот класс в качестве члена:
public class MyClass
{
public MyControl MyMember;
}
Объявить интерфейс ISelf (из T) [*], который включает в себя функцию "Self", которая возвращает T. Поддерживает ли ваш интерфейс не общую и общую версию, где общая версия наследует как не общую версию, так и Сам себе (сам по себе). Затем вы можете наследовать класс как от ISelf (Control), так и от ISelf (от IMyInterface) и объявить свое поле MyMember типом ISelf (IMyInterface (of Control)). Затем MyMember может использоваться как iMyInterface и MyMember.Self как элемент управления. Любое количество интерфейсов может быть объединено таким образом.
[*] Синтаксис VB для дженериков, используемых для того, чтобы избежать угловых скобок, обработанных как HTML-теги.
Используйте силу наследования на интерфейсе
public interface IMyInterface : Control
{
..
}
Теперь вы говорите, что хотите элемент управления с некоторыми специальными методами.
EDIT: TcK, конечно, правы. Вы не можете наследовать интерфейс из конкретного класса.
Одним из способов решения этой проблемы может быть расширение интерфейса с помощью свойства или метода, который возвращает элемент управления.
Пример:
public interface IMyInterface
{
Control Control { get; }
[..rest of the definition..]
}
и реализовать его следующим образом:
class MyControl : Control, IMyInterface
{
public Control Control { get { return this; } }
[..rest of the implementation..]
}
Это звучит принципиально неправильно.
Объявляет ли IMyInterface только те же методы/свойства, что и в классе Control? Если нет, чего вы надеетесь достичь? Вы не можете реализовать интерфейс и игнорировать объявленные в нем методы - вы должны явно записать реализации.
Если IMyInterface фактически объявляет те же методы/свойства, что и в классе Control, вам нужно будет создать свой собственный класс MyControl, который наследует от Control и реализует IMyInterface. Это не какая-то глупая причуда языка. Класс Control не был определен как IMyInterface, а С# - это статически типизированный, а не "утиный" язык, поэтому он не может автоматически выдавать управление любому желаемому интерфейсу.