Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为两种完全不同的类型编写通用方法_C# - Fatal编程技术网

C# 为两种完全不同的类型编写通用方法

C# 为两种完全不同的类型编写通用方法,c#,C#,我目前正在为其他人的代码添加附加内容,并且遇到了一个使用PdfSharp dll的PdfBuilder类。在此之前,该类在构造函数中采用了名为BoxRequest的类型。像这样: public PdfDocument GenerateAddressLabelPdf(int id) { var box = _unitOfWork.BoxRepository.GetById(id); var generator = new PdfBuilder(box

我目前正在为其他人的代码添加附加内容,并且遇到了一个使用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
     }
公共类PdfBuilder
{
私有只读T_pdfType;
公共PdfBuilder(T)
{
_pdfType=t;
}
//额外的课程内容
}
但是现在我有点困惑,我应该如何使
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
使用它(这将是一种更干净的方式)


你不太可能需要仿制药。您需要从BoxRequest和FileRequest中提取接口,或者\并为它们创建单独的PdfBuilder类(当然是从其中一个类继承)。也许你可以让它成为一个由所有具体对象实现的接口?如果所有不同之处都是
GetText
那么覆盖
BoxRequest
和其他类
ToString
方法,而完全不关心类型如何?您可以将
GetText()
替换为某个
input.ToString()
否则,将
GetText()
提取到一个接口,并让这两个类以适当的方式实现
FileRequest
对象是否具有
名称
部门
位置.LocationName
属性,就像
BoxRequest
?也就是说:打印的方法是完全相同还是不同?还有一种方法是将生成文本的函数传递给构造函数:public PdfBuilder(Func textBuilder)。毕竟,您的PdfBuilder并不关心特定的需求(至少在显示的代码中)。它所关心的只是提供一些文本。我个人赞成用
GetText()
方法声明一个新的
IPdfPrintable
接口,以便:1)
PdfBuilder
需要该接口的对象(而不是任何对象);2)
ToString()
的众所周知的含义没有改变。
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);          

        // ...
    }
}