Как проверить во время выполнения, реализует ли класс определенный интерфейс? - PullRequest
1 голос
/ 19 апреля 2010

Допустим, у меня есть несколько классов контента, таких как Page, TabGroup, Tab и т. Д. Некоторые из них будут реализовывать мой интерфейс IWidgetContainer - это означает, что они получат дополнительное поле с именем ContainedItems из интерфейса и некоторые методы для управления этим полем.

Теперь мне нужно отразить тот факт, что некоторые классы реализуют этот интерфейс, выдавая некоторые специальные пользовательские элементы управления в моих представлениях ASP.NET MVC (например, кнопки jQuery Add / Remove / Move / Reorder).

Например, TabGroup будет реализовывать IWidgetContainer, потому что он будет содержать вкладки, но вкладка не будет реализовывать его, потому что у него не будет возможности содержать что-либо.

Поэтому я должен как-то проверить в своем представлении, когда я рендеринг своих объектов содержимого (проблема в том, что я использую свой базовый класс как строгий тип в моем представлении, а не конкретные классы), реализует ли он IWidgetContainer.

Как это возможно, или я что-то пропустил?

Чтобы перефразировать вопрос, как вы отражаете некоторые специальные свойства класса (например, реализацию интерфейса) в пользовательском интерфейсе в целом (не обязательно ASP.NET MVC)?

Вот мой код:

[DataContract]
public class ContentClass
{
    [DataMember]
    public string Slug;

    [DataMember]
    public string Title;

    [DataMember]
    protected ContentType Type;
}

[DataContract]
public class Group : ContentClass, IWidgetContainer
{
    public Group()
    {
        Type = ContentType.TabGroup;
    }

    public ContentList ContainedItems
    {
        get; set;
    }

    public void AddContent(ContentListItem toAdd)
    {
        throw new NotImplementedException();
    }

    public void RemoveContent(ContentListItem toRemove)
    {
        throw new NotImplementedException();
    }
}

[DataContract]
public class GroupElement : ContentClass
{
    public GroupElement()
    {
        Type = ContentType.Tab;
    }
}
1015 * * Интерфейс:
interface IWidgetContainer
{
    [DataMember]
    ContentList ContainedItems { get; set; }

    void AddContent(ContentListItem toAdd);
    void RemoveContent(ContentListItem toRemove);

}

Ответы [ 3 ]

3 голосов
/ 19 апреля 2010

Я думаю, что вы ищете

 void Foo(ContentClass cc)
 {
    if (cc is IWidgetContainer) 
    {
        IWidgetContainer iw = (IWidgetContainer)cc;
        // use iw
    }

 }
2 голосов
/ 19 апреля 2010

Возможно, я неправильно понял ваш вопрос, но есть ли проблема с использованием ключевого слова is?

<% if (obj is IWidgetContainer) { %>
    <!-- Do something to render container-specific elements -->
<% } %>
0 голосов
/ 11 января 2012

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

public static class ObjectTools
{
        public static bool Implements(Type sourceType, Type implementedType)
        {
            if(implementedType.IsAssignableFrom(sourceType))
            {
                return true;
            }
            return false;
        }
}

Все, что вам нужно сделать, - это ввести тип, который вы проверяете, в параметр sourceType (X), и тип, с которым вы проверяете, в параметр connectedType (Y), например, так:

Console.WriteLine(ObjectTools.Implements(typeof(X), typeof(Y)));
...