返回方法之外的一次性对象



如何在方法之外返回PdfDocument来读取对象的属性?我知道该方法将抛出object is disposed异常,因为using将在返回之前完成处理工作。

我在寻求重构的想法。也许Actions适合这里?请提供代码想法。

public PdfDocument Info(string inFile, string password)
{
try
{
using (var pdf = new PdfDocument(inFile, new PdfStandardDecryptionHandler(password)))
{
return pdf;
}
}
catch (IncorrectPasswordException)
{
throw new ApiException(ResponseMessageType.FilePasswordProtected);
}
catch (UnexpectedStructureException)
{
throw new ApiException(ResponseMessageType.FileDamaged);
}
}

using语句实际上是try{}finally{}构造的语法糖,编译器将其降低如下:

// this ...
using(var thing = new DisposableThing())
{
...
}
// gets rewritten to:
var thing = new DisposableThing();
try
{
...
}
finally
{
if(thing is IDisposable)
{
((IDisposable)thing).Dispose();
}
}

因此,从您的方法中删除using语句以防止过早处理:

public PdfDocument Info(string inFile, string password)
{
try
{
return new PdfDocument(inFile, new PdfStandardDecryptionHandler(password));
}
catch (IncorrectPasswordException)
{
throw new ApiException(ResponseMessageType.FilePasswordProtected);
}
catch (UnexpectedStructureException)
{
throw new ApiException(ResponseMessageType.FileDamaged);
}
}

在这一点上,消费者有责任处理它:

using (var pdf = Info(inFile, password))
{
// read properties from `pdf` here
}

首先,如果您想返回一个一次性对象,那么调用方函数应该处理处理;因此,不需要在对象创建函数中使用using语句。

当您想调用Info函数来创建PdfDocument对象时,请使用try来调用"信息(字符串,字符串(";然后在finally块中处理它(如果它不是null(。

public PdfDocument Info(string inFile, string password)
{
try
{
PdfDocument pdf = new PdfDocument(inFile, new PdfStandardDecryptionHandler(password));
return pdf;
}
catch (IncorrectPasswordException)
{
throw new ApiException(ResponseMessageType.FilePasswordProtected);
}
catch (UnexpectedStructureException)
{
throw new ApiException(ResponseMessageType.FileDamaged);
}
}
/////////////
AnotherFunction()
{
PdfDocument pdf = null;
try
{
pdf = Info("inFile", "password");
// Use the object
}
finally
{
pdf?.Dispose();
}
}

换一种方式,不返回对象,而是注入Action怎么样?

public void ProcessPdf(string inFile, string password, Action<PdfDocument> action)
{
try
{
using (var pdf = new PdfDocument(inFile, new PdfStandardDecryptionHandler(password)))
{
action (pdf);
}
}
catch (IncorrectPasswordException)
{
throw new ApiException(ResponseMessageType.FilePasswordProtected);
}
catch (UnexpectedStructureException)
{
throw new ApiException(ResponseMessageType.FileDamaged);
}
}

称之为:

ProcessPdf(iniPath, "*****", (o) => DoSomething(o))
private void DoSomething (pdfDocument doc)
{
//....
}

伪代码,未测试!

最新更新