2013-12-18 72 views
9

我正在做一個類的重構,並想在一個單獨的方法中移動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); 

    } 
} 

在調用編譯器的方法拋出異常:只讀局部變量不能作爲分配對象的doc和MEM。

編輯:這裏只有我在pdf文件中添加內容的另一種方法。所以我需要傳遞相同的doc對象,對吧?所以爲什麼我不能使用ref或輸出param

技術上using藐視ref參數在這裏的目的。

試圖尋找在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. 

怎麼成爲讀取的對象僅在調用方法的?在範圍內對象是活着的,你可以做任何你想做的事情。

+0

請顯示一個簡短但完整的程序來展示問題。 –

+0

不,這不是一個簡短但完整的程序。通過「簡短但完整的程序」,我的意思是「我可以複製並粘貼到新文本文件中的東西,編譯和運行時不做任何更改」。 –

+0

嘗試複製並粘貼到一個新的文本文件並編譯它。什麼是「文檔」類?什麼是「PdfWriter」類? 'Paragraph'? 'Chunk'? 'Phrase'?我強烈懷疑它們與這個問題無關,而且你只需要一些*'IDisposable'實現 - 所以在BCL中使用一個,並添加一個合適的'using'指令。 –

回答

12

這是因爲您使用using關鍵字聲明docmem。援引MSDN

內使用塊,所述對象是隻讀,不能被修改或重新分配。

因此,您會收到有關只讀變量的錯誤。


如果你一直希望通過引用傳遞參數,你可以使用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(); 
+0

+1幫助並向我解釋,但這並不能解決我的問題。 – joshua

+0

請參閱我的編輯以解決此問題。 – Szymon

+1

這個*不是和'using'一樣的代碼 - 因爲使用'using'語句,它總是被處理的* original *對象。在你的「等價」代碼中,如果AddContent改變了doc的值,它就是在Dispose調用中使用的後面的值。 –

6

mem變量是隻讀的,因爲using關鍵字。編譯器應該如何知道當你重寫它對變量的引用時,在離開使用範圍時他必須處置什麼。

但是,爲什麼您必須使用ref關鍵字呢?在我看來,你不需要參考。

+0

可能不需要在這裏。需要生成pdf文檔,你需要保留相同的文檔對象。這就是我所做的。 – joshua

+0

從理論上講,'using'的合約可能只是「在塊末尾的變量中放置任何東西」,所以如果將它切換出來,它只會處理任何切換它的東西......但它不是: )+1「你不需要參考」。 – Rawling

+0

@joshua:你真的*需要確保你明白'ref'的作用。正確使用C#非常重要。查看問題評論中包含的鏈接。我很確定刪除'ref'是這裏最好的*解決方案。 –