I was doing a refactoring of class and thought of moving 100 lines in a separate method. Like this:
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);
}
}
At calling method of Compiler throws exception : Readonly local variable cannot be used as an assignment target for doc and mem.
Edit: here only i adding content in pdf
document in another method. so i need to pass same doc object, right ? so why can't i use ref
or out param
.
Technically using
defies the purpose of ref
param here.
Tried to look on 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.
How the objects become read only at calling of Method? Within the scope object is alive and you can do whatever you want.
IDisposable is an interface that contains a single method, Dispose(), for releasing unmanaged resources, like files, streams, database connections and so on.
IDisposable is an interface that contains only a single method i.e. Dispose(), for releasing unmanaged resources. IDisposable is defined in the System namespace. It provides a mechanism for releasing unmanaged resources.
Classes such as Stream , StreamReader , StreamWriter etc implements IDisposable interface.
In a nutshell, an IDisposable class allows you to explicitly handle the deallocation of resources (typically unmanaged resources or database connections) via the Dispose() method. IDisposable class instances should be created within a "Using" block so as to ensure that the Dispose method is actually called.
This is because you declare doc
and mem
using the using
keyword. Citing MSDN:
Within the using block, the object is read-only and cannot be modified or reassigned.
Hence you get the error about the read-only variable.
If you still want to pass parameters by reference, you can use try ... finally
block instead of using
. As pointed out by Jon Skeet, this code is similar to how using
is expanded but with a using
statement, it's always the original object which is disposed. In the code below, if AddContent
changes the value of doc
, it will be that later value which is used in the Dispose
call.
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();
the mem
variable is readonly, because of the using
keyword. How should the compiler know otherwise what he has to dispose when leaving the using-scope when you override it's reference to the variable.
But why do you have to use the ref
keyword anyway? In my opinion you do not need a ref.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With