IDisposable对象作为ref param to方法

时间:2013-12-18 10:34:52

标签: c#

我正在进行类的重构,并考虑在一个单独的方法中移动100行。像这样:

using iTextSharp.text;
using iTextSharp.text.pdf;

 class Program
{
    private static void Main(string[] args)
    {
        Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 35);
        using (var mem = new MemoryStream())
        {
            using (PdfWriter wri = PdfWriter.GetInstance(doc, mem))
            {
                doc.Open();
                AddContent(ref doc, ref wri);
                doc.Close();
                File.WriteAllBytes(@"C:\testpdf.pdf", mem.ToArray());
            }
        }
    }

    public static void AddContent(ref Document doc, ref PdfWriter writer)
    {
        var header = new Paragraph("My Document") { Alignment = Element.ALIGN_CENTER };
        var paragraph = new Paragraph("Testing the iText pdf.");
        var phrase = new Phrase("This is a phrase but testing some formatting also. \nNew line here.");
        var chunk = new Chunk("This is a chunk.");
        doc.Add(header);
        doc.Add(paragraph);
        doc.Add(phrase);
        doc.Add(chunk);

    }
}

在调用Compiler方法时抛出异常: 只读局部变量不能用作doc和mem的赋值目标

编辑:此处我只在另一种方法中添加pdf文档中的内容。所以我需要传递相同的doc对象,对吧?那么为什么我不能使用refparam

技术上using违反了ref param的目的。

试图查看MSDN:

A ReadOnly property has been found in a context that assigns a value to it. 
Only writable variables, properties, and array elements can have values assigned
to them during execution.

如何在调用Method时读取对象?在范围内,对象是活着的,你可以随心所欲。

2 个答案:

答案 0 :(得分:12)

这是因为您使用doc关键字声明了memusing。引用MSDN

  

在using块中,该对象是只读的,不能修改或重新分配。

因此,您收到有关只读变量的错误。


如果您仍想通过引用传递参数,则可以使用try ... finally块而不是using。正如Jon Skeet所指出的,这段代码类似于using的扩展方式,但是使用using语句,它始终是处理的原始对象。在下面的代码中,如果AddContent更改了doc的值,那么它将是Dispose调用中使用的更晚值。

var doc = new Document(PageSize.A4, 5f, 5f, 5f, 5f);
try
{
     var mem = new MemoryStream();
     try
     {
         PdfWriter wri = PdfWriter.GetInstance(doc, output);
         doc.Open();
         AddContent(ref doc,ref wri );
         doc.Close();
     }
     finally
     {
         if (mem != null)
             ((IDisposable)mem).Dispose();
     }
 }
 finally
 {
     if (doc != null)
         ((IDisposable)doc).Dispose();
 }
 return output.ToArray();

答案 1 :(得分:6)

由于mem关键字,using变量是只读的。当你覆盖它对变量的引用时,编译器应该如何知道在离开使用范围时他必须处置什么。

但为什么你还要使用ref关键字呢?在我看来,你不需要参考。