2016-12-23 11 views
0

У меня возникают некоторые проблемы при попытке «размножать» общий тип более чем на один уровень подклассов. У меня есть три уровня классов: GenericResponseDtoMapper<T> - это абстрактный класс, а T - это GenericSearchResponseDto.Иерархическое использование генериков

У меня есть два подкласса, которые простираются GenericResponseDtoMapper: SimpleResponseDtoMapper и GroupedResponseDtoMapper. В этих двух подклассах я вынужден указать общий тип; для istance Я должен написать:

SimpleResponseDtoMapper : GenericResponseDtoMapper<GenericResponseDtoMapper>.

И наконец, у меня есть классы, которые расширяют SimpleResponseDtoMapper и некоторые другие, которые расширяют GroupedResponseDtoMapper. Моя проблема в том, что я не могу указать подтип GenericSearchResponseDto на этом уровне.

Итак, как я управляю родовыми типами, чтобы оставить общий тип для первого и второго слоев классов, оставив более низкий уровень классов использовать указанный тип родового типа?

Вот код:

public abstract class GenericResponseDtoMapper<T> : IResponseDtoMapperDecorator where T : GenericSearchResponseDto 
{ 
    protected List<T> items; 

    public GenericResponseDtoMapper() 
    { 
     items = new List<T>(); 
    } 

    public abstract IList<T> GetItems(IList<Entity.FullText_xml.DreDoc> documents); 
} 

Класс SimpleResponseDtoBuilder:

public abstract class SimpleResponseDtoBuilder : GenericResponseDtoMapper<GenericSearchResponseDto> 
{ 
    public SimpleResponseDtoBuilder() : base() { } 

    public override IList<GenericSearchResponseDto> GetItems(IList<DreDoc> documents) 
    { 
     foreach (var doc in documents) 
     { 
      var item = new GenericSearchResponseDto(); 

      item.IdDatabank = doc.Field.IdDatabank; 
      item.IdDocMaster = doc.Field.IdDocMaster; 
      item.DescDatabank = doc.Field.DescDatabank; 
      item.Materie = doc.Field.MateriaAll.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries); 
      item = setResponseParams(item, doc); 

      items.Add(item); 
     } 

     return items; 
    } 

    public abstract GenericSearchResponseDto setResponseParams(GenericSearchResponseDto item, DreDoc doc); 
} 

И наконец конкретная реализация:

public class GiurisprudenzaResponseDtoBuilder : SimpleResponseDtoBuilder 
{ 
    private HighlightHelper _highLightHelper; 

    private const string _BR = @"<br/>"; 

    public GiurisprudenzaResponseDtoBuilder() : base() 
    { 
     _highLightHelper = new HighlightHelper(); 
    } 

    public override IList<GiurisprudenzaSearchResponseDto> GetItems(IList<DreDoc> documents) 
    { 
     return base.GetItems(documents); 
    } 

    public override GiurisprudenzaSearchResponseDto setResponseParams(GiurisprudenzaSearchResponseDto item, DreDoc doc) 
    { 

     item.IdUnitaDoc = doc.Field.IdUnitaDoc; 

     ... some item.Something = doc.Something... 

     return item; 
    } 

UML Class Diagram

+6

Эта проблема весьма симптоматично пытается решить слишком много проблем бизнеса в системе типа. Даже если вы можете заставить его работать, никто не поймет отношения между типами; если это сложнее, чем «корзина апельсинов, корзина яблок», то будущие программисты не поймут это легко. Спросите себя: «Если бы у меня не было дженериков, какие интерфейсы я использовал бы для решения этой проблемы?» и пусть это поможет вашему дизайну. –

ответ

0

Способ размножения универсального типа в течение более чем одного слоя подклассы в C# является следующее:

public TopClass<T> where T : GenericType{ 
} 

public MiddleClass<T> : TopClass<T> where T : GenericType{ 
} 

public BottomClass : MiddleClass<SpecificType>{ 
}