2013-06-24 2 views
1

Учитывая этот код:Интерфейс C#, обеспечивающий свойство, являющееся другим интерфейсом?

public interface ITagModel { } 

public interface ITemplate { 
    ITagModel Model { get; set; } 
} 

public class EmailTag : ITagModel { } 

public class EmailTest : ITemplate { 
    public EmailTag Model { get; set; } 
} 

мне говорят, что тип EmailTag (внутри EmailClass) не может реализовать свойство Model, потому что это не тип ITagModel.

Это наследует ITagModel .... так почему бы не работать? Что я могу сделать, чтобы выполнить то, что я ищу?

ответ

5

C# не поддерживает covariant return.

например.

public class Base { } 
public class Derived : Base { } 

public class Component 
{ 
    public virtual Base GetComponent() 
    { 
     return new Base(); 
    } 
} 

public class DerviedComponent : Component 
{ 
    public override Dervied GetComponent() 
    { 
     return new Derived(); 
    } 
} 

Таким образом, вам нужно будет абстрагироваться от типа возврата и сдержать его на свой интерфейс. Таким образом, любая реализация должна будет предоставить ITagModel.

public interface ITagModel { } 

public interface ITemplate<TModel> 
    where TModel : ITagModel 
{ 
    TModel Model { get; set; } 
} 

public class EmailTag : ITagModel { } 

public class EmailTest : ITemplate<EmailTag> { 
    public EmailTag Model { get; set; } 
} 
+0

Я знал, что у меня есть мозговой пердит. Возможно, я работал с Javascript слишком много недель. –

2

Это звучит как ваш интерфейс ITemplate должен быть универсальным:

public interface ITemplate<TModel> where TModel : ITagModel 
{ 
    TModel Model { get; set; } 
} 

Тогда:

public class EmailTest : ITemplate<EmailTag> 
{ 
    public EmailTag Model { get; set; } 
} 

Представьте, если ваш текущий код работал. Тогда я мог бы написать:

ITemplate template = new EmailTest(); 
template.Model = new SomeOtherModel(); 

... и вы не захотите этого. (В принципе, вы будете нарушать безопасность типов.)