Могу ли я указать интерфейсы при объявлении участника?

Мне нужен член моего класса, чтобы он был элементом управления, и чтобы он реализовывал интерфейс, который мы определяем.

Если я объявлю это так...

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;
}

... за исключением того, что ни одна из этих работ. Могу ли я указать интерфейсы при объявлении участника, и если да, то как?

6 ответов

Вы можете использовать дженерики с ограничениями:

public interface MyClass {
    public T GetMyControl() where T : Control, IMyInterface { /* ........ */ }
}

Так как написать класс-оболочку для Control и простой универсальный класс очень сложно:

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();
            }
        }
    }
}

Объявите интерфейс ISelf(из T) [*], который включает функцию "Self", которая возвращает T. Пусть ваш интерфейс поддерживает неуниверсальную и универсальную версию, где универсальная версия наследует и неуниверсальную версию, и ISelf(из сам). Затем вы можете иметь класс, унаследованный от ISelf(из Control) и ISelf(из IMyInterface), и объявить поле MyMember типа ISelf(из IMyInterface(из Control)). Затем MyMember может использоваться как iMyInterface, а MyMember.Self - как элемент управления. Любое количество интерфейсов может быть объединено таким образом.

[*] Синтаксис VB для обобщений используется, чтобы избежать обработки угловых скобок как тегов HTML.

Вы можете иметь свой собственный класс, полученный из элемента управления с интерфейсом, определенным как:

class MyControl : Control, IMyInterface
{
}

а затем использовать этот класс в качестве члена:

public class MyClass
{
    public MyControl MyMember;
}

Используйте силу наследования на интерфейсе

public interface IMyInterface : Control
{
  ..
}

Теперь вы говорите, что хотите контроль с некоторыми специальными методами.


РЕДАКТИРОВАТЬ: TcKs, конечно, правильно.. вы не можете наследовать интерфейс от конкретного класса.

Одним из способов решения этой проблемы может быть расширение интерфейса с помощью свойства или метода, который возвращает элемент управления.

Образец:

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, а C# является статически типизированным, а не "утиным" языком, поэтому он не может автоматически предоставить Control любой интерфейс, какой вы пожелаете.

Другие вопросы по тегам