Tuesday, 25 May 2010

No Implicit Conversion When Passing Parameters By Reference

We all know that when passing a parameter to a method by reference using the ref keyword, two things are important:

1). the variable must be explicitly assigned first.
2). the variable doesn't create a new storage location (in terms of reference type) or new copy (in terms of value type).

However, one undocumented (by undocumented I mean it is neither in C# specification nor MSDN) feature of passing parameter by ref is the declaration type of the variable passed in must match exactly the declaration type of the parameter in the method. For example, if you have a method like this:

  public void RefMe(ref ValueType pop)
{

}

then the following code will give you a compile error:

int number = 3;
RefMe(ref number);

Even though integer is subtype of ValueType, but implicit conversion/casting is not possible when passing parameters reference. The variable declaration type must match the method parameter type exactly.

Don't attempt the following either :

RefMe(ref (ValueType)number); It will emit a compile error.

You have to do the casting before the method call:

int number = 3;
ValueType val = number;
RefMe(ref val);
or
ValueType number = 3;
RefMe(ref number);

but be aware that for value types, declaring another variable creates a new copy of the data, which may defeat the purpose of passing a variable by reference. However, it is fine for reference type though.




















Wednesday, 12 May 2010

C# Array Literal?

C# allows you to declare an array in the following way:

string[] strArray = { "a","b" };

thus gives you the illusion that { "a","b" } is an array liberal, just like "good string" is a string literal, because you can declare a string like this:

string myString = "good string";

However, if you pass { "a","b" } directly to a method that take string array as a parameter, e.g. String.Split(), you will get a compile error. It has to be done like this:
{ "a","b" } is just a short cut for compiler when declaring an array, in the same way that var is used. It is not an array literal. Actually If you use var in combination with { "a","b" } as below, you will get a compile error, as compiler cannot infer the type you want to declare.

var mySring = {"a", "b"};

You have to specify the type explicitly in either side of the equation:

string[] myString = {"a", "b"};

or

var myString = new[] {"a", "b"};


The easiest way to remember this is that when declaring an array, a pair of square brackets ([]) is mandatory! So, if you want to pass an array as a parameter to a method without giving the array a variable name, use this form:

new[]{ , , ,.....}