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

问题描述:

我目前向别人的代码中添加了附加内容,并遇到了使用PdfSharp dll的PdfBuilder类。直到此时,该类在构造函数中采用了称为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,然后检查类型并根据类型添加不同的行,但它看起来不再是通用的?

+1

这不太可能需要泛型。您需要从BoxRequest和FileRequest或\中提取接口,并为它们创建单独的PdfBuilder类(从当然继承)。 – Evk

+1

也许你可以让T成为一个由所有具体对象实现的接口? –

+1

如果所有不同的是'GetText'如何重写'BoxRequest'和其他类'ToString'方法而不关心类型?你可以用'替换'GetText()'。 'input.ToString()'否则,将'GetText()'提取到一个接口并让两个类以合适的方式实现 – nozzleman

我不认为仿制药的处理这个问题的最好方式......

如果所有不同的是,多数民众赞成在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消耗(这将是更清洁的海事组织)。

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

     // ... 
    } 
} 
+0

我个人赞成用'GetText()'方法声明一个新的'IPdfPrintable'接口,以便:1)'PdfBuilder'需要该接口的对象(而不是任何对象)。 2)'ToString()'的众所周知的含义是不变的。 –

+0

我只是编辑exaclty,D – nozzleman

+0

有道理,谢谢! – JsonStatham