我可以以某种方式整理这种(过度使用?)的仿制药吗?

Jef*_*aes 6 c# generics types design-patterns

我正在构建一个通用的平面文件阅读器,看起来像这样.

 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;
    }        
}
Run Code Online (Sandbox Code Playgroud)

它可以像这样消费.

var reader = new GenericReader<Composite<Header, Data, Trailer>, Header, Data, Trailer> ();

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

Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)

这是使用的类.

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"; } } 
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在GenericReader中删除或封装泛型类型信息?我正在寻找一双额外的眼睛向我展示我一直缺少的东西.我们已经对返回接口做了一些事情,并让消费者做了演员表,但是我认为这只会把责任移到错误的位置,而且性能会受到很小的影响.

谢谢.

编辑:我不需要TComposite,我只能返回GenericComposite.我怎么能错过这个?

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; }
}
Run Code Online (Sandbox Code Playgroud)

cas*_*One 2

没有办法消除对您所拥有的泛型约束的类型声明的需要。

但是,您的用例表明这是最常见的行为:

var reader = new GenericReader<Composite<Header, Data, Trailer>, 
    Header, Data, Trailer>();
Run Code Online (Sandbox Code Playgroud)

如果是这种情况,您可以假设某些模式的使用频率,则可以从具有封闭类型定义的泛型类继承一个类型(或一组类型),这样可以更轻松地使用。

在上述情况下,您可以为基本、最常见的情况提供这些类(除了通用定义之外):

public class Composite : GenericComposite<Header, Data, Trailer> { }

public class GenericReader : GenericReader<
    Composite, Header, Data, Trailer>
{ }
Run Code Online (Sandbox Code Playgroud)

然后将像这样使用:

var reader = new GenericReader();

var composite = reader.Read();

Console.WriteLine(composite.Data.SomeProperty);

Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)

您仍然可以拥有具有通用参数的类型,用于高度专业化的情况,但对于常见用例(您通过分析/领域知识确定),您可以确定最常见的类型并提供具有集合类型的类参数来协助。