为两种完全不同的类型编写泛型方法

本文关键字:类型 泛型方法 两种 | 更新日期: 2023-09-27 18:17:44

我目前正在添加其他人的代码,并遇到了一个PdfBuilder类,它正在使用PdfSharp dll。到目前为止,该类在构造函数中采用了一个称为BoxRequest的类型。像这样:

    public PdfDocument GenerateAddressLabelPdf(int id)
    {
        var box = _unitOfWork.BoxRepository.GetById(id);
        var generator = new PdfBuilder(box);
        return generator.BuildPdfDocument();
    }

PdfBuilder类是这样的:

    public class PdfBuilder
    {
        private readonly BoxRequest _boxRequest;
        public PdfBuilder(BoxRequest boxRequest)
        {
            _boxRequest = boxRequest;
        }
        public PdfDocument BuildPdfDocument()
        {
            PdfDocument pdfDocument = new PdfDocument();
            PdfPage page = pdfDocument.AddPage();
            page.Orientation = PageOrientation.Landscape;
            XGraphics gfx = XGraphics.FromPdfPage(page);
            XFont font = new XFont("Arial", 40, XFontStyle.Regular);
            XTextFormatter tf = new XTextFormatter(gfx);
            XRect rect = new XRect(0, (page.Height/4), page.Width, page.Height);
            gfx.DrawRectangle(XBrushes.White, rect);
            tf.Alignment = XParagraphAlignment.Center;
            tf.DrawString(GetText(), font, XBrushes.Black, rect);          
            return pdfDocument;
        }
        private string GetText()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(_boxRequest.Name);
            sb.AppendLine(_boxRequest.Department);
            sb.AppendLine(_boxRequest.Location.LocationName);
            return sb.ToString();
        }
    }

因此,您可以看到GetText中使用的属性取自FileRequest类型。

我现在需要再次使用这个类,这次是一个名为FileRequest的新类型,当我调用这个类并看到它只需要一个BoxRequest时,我认为这可能是一个很好的泛型。

到目前为止,我已经改变了类,如下所示:
    public class PdfBuilder<T>
    {
        private readonly T _pdfType;
        public PdfBuilder(T t)
        {
            _pdfType = t;
        }
        //additional class stuff
     }

但是现在我有点困惑,我应该如何使GetText方法通用,因为我需要为每种类型渲染某些行。

在这一点上,我想我可以把类型传递给GetText,然后检查类型,并根据类型追加不同的行,但它似乎不再是真正的通用?

为两种完全不同的类型编写泛型方法

我不认为泛型是处理这个问题的最好方法…

如果所有的不同是GetText,最简单的(不是最好的)解决这个问题的方法是重写BoxRequest和其他类的ToString()方法,根本不关心类型。

public class BoxRequest
{
    // ...
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine(this.Name);
        sb.AppendLine(this.Department);
        sb.AppendLine(this.Location.LocationName);
        return sb.ToString();
    }
}
public class PdfBuilder
{
    private readonly object request;
    public PdfBuilder(object request)
    {
        this.request = request;
    }
    public PdfDocument BuildPdfDocument()
    {
        // ...
        tf.DrawString(request.ToString(), font, XBrushes.Black, rect);          
        // ...
    }
}
这样,您就可以使用这个类来PDF任何对象。如果这对你来说是通用的(对我来说是),你可以为ToString()/GetText()提取一个接口,让你的PdfBuilder使用它(这将是更干净的IMO)。
public interface IPdfConvertible
{
    public string GetText()
}
// same for FileRequest...
public class BoxRequest : IPdfConvertible
{
    // ...
    public string GetText()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine(this.Name);
        sb.AppendLine(this.Department);
        sb.AppendLine(this.Location.LocationName);
        return sb.ToString();
    }
}
public class PdfBuilder
{
    private readonly IPdfConvertible request;
    public PdfBuilder(IPdfConvertible request)
    {
        this.request = request;
    }
    public PdfDocument BuildPdfDocument()
    {
        // ...
        tf.DrawString(request.GetText(), font, XBrushes.Black, rect);          
        // ...
    }
}