2013-12-18 21 views
9

Tôi đã thực hiện tái cấu trúc lớp và nghĩ đến việc di chuyển 100 dòng trong một phương thức riêng biệt. Như thế này:Đối tượng IDisposable là tham số ref cho phương thức

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

    } 
} 

Tại phương pháp biên dịch kêu gọi ném ngoại lệ: biến cục bộ chỉ đọc không thể được sử dụng như một mục tiêu chuyển nhượng cho doc và mem.

Chỉnh sửa: tại đây chỉ tôi thêm nội dung trong tài liệu pdf vào một phương pháp khác. vì vậy tôi cần phải vượt qua cùng một đối tượng doc, phải không? vậy tại sao tôi không thể sử dụng ref hoặc ra param.

Về mặt kỹ thuật using bất chấp mục đích của ref thông số tại đây.

Cố gắng tìm trên 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. 

Làm thế nào các đối tượng trở nên đọc chỉ kêu gọi của phương pháp? Trong phạm vi đối tượng là còn sống và bạn có thể làm bất cứ điều gì bạn muốn.

+0

Vui lòng hiển thị chương trình ngắn nhưng * hoàn chỉnh để minh họa sự cố. –

+0

Không, đó không phải là một chương trình ngắn nhưng đầy đủ. "Ngắn nhưng hoàn thành chương trình" Tôi có nghĩa là "cái gì tôi có thể sao chép và dán vào một tập tin văn bản mới, biên dịch và chạy không có thay đổi". –

+0

Thử sao chép và dán vào một tệp văn bản mới và biên dịch nó. Lớp 'Document' là gì? Lớp 'PdfWriter' là gì? 'Đoạn'? 'Chunk'? 'Cụm từ'? Tôi mạnh mẽ nghi ngờ họ không liên quan đến câu hỏi, và rằng bạn chỉ cần * một số * 'IDisposable' thực hiện - vì vậy sử dụng một trong BCL, và thêm một chỉ thị' using' thích hợp. –

Trả lời

12

Điều này là do bạn khai báo docmem sử dụng từ khóa using. Trích dẫn MSDN:

Trong khối đang sử dụng, đối tượng này chỉ đọc và không thể sửa đổi hoặc gán lại.

Do đó bạn gặp lỗi về biến chỉ đọc.


Nếu bạn vẫn muốn truyền tham số bằng cách tham khảo, bạn có thể sử dụng try ... finally khối thay vì using. Như đã chỉ ra bởi Jon Skeet, mã này tương tự như cách using được mở rộng nhưng với câu lệnh using, nó luôn là đối tượng ban đầu được xử lý. Trong mã bên dưới, nếu AddContent thay đổi giá trị của doc, giá trị sau đó sẽ được sử dụng trong cuộc gọi 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 để được trợ giúp và giải thích cho tôi, nhưng điều này không giải quyết được vấn đề của tôi. – joshua

+0

Xem bản chỉnh sửa của tôi để biết cách giải quyết vấn đề này. – Szymon

+1

Điều này * không phải * cùng mã với 'using' - bởi vì với câu lệnh' using', nó luôn là đối tượng * nguyên bản * được xử lý. Trong mã "tương đương" của bạn, nếu 'AddContent' thay đổi giá trị của' doc', nó sẽ là giá trị sau đó được sử dụng trong lệnh 'Dispose'. –

6

biến số mem là chỉ đọc, vì từ khóa using. Làm thế nào trình biên dịch nên biết nếu không những gì anh ta phải xử lý khi rời khỏi phạm vi sử dụng khi bạn ghi đè lên nó tham chiếu đến biến.

Nhưng tại sao bạn vẫn phải sử dụng từ khóa ref? Theo tôi, bạn không cần ref.

+0

có thể được ref wont yêu cầu ở đây. yêu cầu tạo ra tài liệu 'pdf', bạn cần giữ lại cùng một đối tượng tài liệu. Đây là những gì tôi đã làm. – joshua

+0

Về lý thuyết, hợp đồng xung quanh 'using' có thể chỉ là" xử lý bất cứ điều gì trong biến ở cuối khối ", vì vậy nếu bạn chuyển đổi nó sẽ chỉ vứt bỏ bất cứ điều gì bạn chuyển nó cho ... nhưng nó không phải:) +1 cho "bạn không cần ref". – Rawling

+0

@joshua: Bạn * thực sự * cần phải chắc chắn rằng bạn hiểu những gì 'ref' nào. Điều quan trọng là sử dụng C# đúng cách. Xem liên kết có trong các bình luận câu hỏi. Tôi khá chắc chắn rằng loại bỏ 'ref' là giải pháp * tốt nhất * ở đây. –

Các vấn đề liên quan