Can I somehow tidy up this (overuse?) of generics? I'm building a generic flat file reader which looks something like this.

 public class GenericReader&lt;TComposite, THeader, TData, TTrailer&gt; 
    where TComposite : GenericComposite&lt;THeader, TData, TTrailer&gt;, new()
    where THeader : new()
    where TData : new()
    where TTrailer : new()
{
    public TComposite Read()
    { 
        // read stuff, do parsing etc
        var composite = new TComposite();

        composite.Header = new THeader();
        composite.Data = new TData();
        composite.Trailer = new TTrailer();

        return composite;
    }        
}


It could be consumed like so.

var reader = new GenericReader&lt;Composite&lt;Header, Data, Trailer&gt;, Header, Data, Trailer&gt; ();

var composite = reader.Read();
Console.WriteLine(composite.Data.SomeProperty);

Console.ReadLine();


Here are the classes used.

public class Composite&lt;THeader, TData, TTrailer&gt; : GenericComposite&lt;THeader, TData, TTrailer&gt;
{

}

public class GenericComposite&lt;THeader, TData, TTrailer&gt;
{
    public THeader Header { get; set; }

    public TData Data { get; set; }

    public TTrailer Trailer { get; set; }
}

public class Header {
    public string SomeProperty { get { return "SomeProperty"; } } 
}

public class Data {
    public string SomeProperty { get { return "SomeProperty"; } } 
}

public class Trailer {
    public string SomeProperty { get { return "SomeProperty"; } } 
}


Is there a way how I could remove or encapsulate that generic type information in the GenericReader? I'm looking for an extra pair of eyes to show me something what I've been missing. We already did something with returning interfaces, and making the consumer do a cast, but that just moves the responsibility to the wrong location in my opinion, plus there is a small performance penalty.

Thanks.
Having so many new operations -- seems like you'd want to use some kind of a factory, injected in the constructor, or the instances themselves injected in the constructor, instead of constructing the classes inside the constructor.