Hierarchical use of generics

145 views Asked by At

I'm having some issues when trying to "propagate" a generic type over more than one layer of subclasses. I have three layers of classes : GenericResponseDtoMapper<T> is an abstract class, and T is a GenericSearchResponseDto.

I have two subclasses which extend GenericResponseDtoMapper: SimpleResponseDtoMapper and GroupedResponseDtoMapper. In those two subclasses I'm forced to specify the generic type; for istance I must write:

SimpleResponseDtoMapper : GenericResponseDtoMapper<GenericResponseDtoMapper>.

Finally, I have some classes which extend SimpleResponseDtoMapper and some others that extendGroupedResponseDtoMapper. My problem is that I can't specify a subtype of GenericSearchResponseDto at this level.

So, How I manage generic types in order to leaving the generic type for the first and the second layer of classes, leaving the lower level of classes to use the specified type of the generic type ?

Here is the code:

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

The Class 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);
}

And Finally the specific implementation:

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

1

There are 1 answers

0
davideAlbertini On

A method for propagating a generic type over more than one layer of subclasses in C# is the following:

public TopClass<T> where T : GenericType{
}

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

public BottomClass : MiddleClass<SpecificType>{
}