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

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

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

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 ]

2 голосов
/ 13 ноября 2008

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

public interface MyClass {
    public T GetMyControl() where T : Control, IMyInterface { /* ........ */ }
}
1 голос
/ 13 ноября 2008

Поскольку очень сложно написать класс-оболочку для 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();
            }
        }
    }
}
0 голосов
/ 06 января 2011

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

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

0 голосов
/ 13 ноября 2008

Это звучит в корне неправильно.

Объявляет ли IMyInterface только те же методы / свойства, что и в классе Control? Если нет, что вы надеетесь достичь? Вы не можете реализовать интерфейс и игнорировать объявленные в нем методы - вы должны явно выписать реализации.

Если IMyInterface действительно объявляет только те же методы / свойства, что и в классе Control, вам придется создать свой собственный класс MyControl, который наследуется от Control и реализует IMyInterface. Это не какая-то глупая причуда языка. Класс Control не был определен как IMyInterface, а C # - статически типизированный, а не "утиный" язык, поэтому он не может автоматически предоставить Control любой интерфейс, какой вы пожелаете.

0 голосов
/ 13 ноября 2008

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

class MyControl : Control, IMyInterface
{
}

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

public class MyClass
{
    public MyControl MyMember;
}
0 голосов
/ 13 ноября 2008

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

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..]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...