I am creating a general flat reader that looks something like this.
public class GenericReader<TComposite, THeader, TData, TTrailer> where TComposite : GenericComposite<THeader, TData, TTrailer>, new() where THeader : new() where TData : new() where TTrailer : new() { public TComposite Read() { var composite = new TComposite(); composite.Header = new THeader(); composite.Data = new TData(); composite.Trailer = new TTrailer(); return composite; } }
It can be used like this.
var reader = new GenericReader<Composite<Header, Data, Trailer>, Header, Data, Trailer> (); var composite = reader.Read(); Console.WriteLine(composite.Data.SomeProperty); Console.ReadLine();
Here are the classes used.
public class Composite<THeader, TData, TTrailer> : GenericComposite<THeader, TData, TTrailer> { } public class GenericComposite<THeader, TData, TTrailer> { 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 to remove or encapsulate this generic type information in GenericReader? I am looking for an extra pair of eyes to show me what I was missing. We have already done something with the return of interfaces, and forcing the consumer to make the cast, but this just transfers responsibility to the wrong place, in my opinion, plus a slight decrease in performance.
Thanks.
Edit: I don't need TComposite, I can just return GenericComposite. How could I skip this?
public class GenericReader<THeader, TData, TTrailer> where THeader : new() where TData : new() where TTrailer : new() { public GenericComposite<THeader, TData, TTrailer> Read() { var composite = new GenericComposite<THeader, TData, TTrailer>(); composite.Header = new THeader(); composite.Data = new TData(); composite.Trailer = new TTrailer(); return composite; } } public class GenericComposite<THeader, TData, TTrailer> { public THeader Header { get; set; } public TData Data { get; set; } public TTrailer Trailer { get; set; } }