Recipe9.14.Using Different Parameter Modifiers in Anonymous Methods


Recipe 9.14. Using Different Parameter Modifiers in Anonymous Methods

Problem

You know you can pass parameters to anonymous methods but you need to figure out what parameter modifiers are valid with anonymous methods.

Solution

Anonymous methods can use out and ref parameter modifiers but not the params modifier in their parameter list. However, this does not prevent the creation of delegates with any of these modifiers as shown here:

 // Declare out delegate. delegate int DoOutWork(out string work); // Declare ref delegate. delegate int DoRefWork(ref string work); // Declare params delegate. delegate int DoParamsWork(params string[] workItems); 

Even though the DoParamsWork delegate is defined with the params keyword on the parameter, it can still be used as a type for an anonymous method, as you'll see in a bit. To use the DoOutWork delegate, create an anonymous method inline using the out keyword and assign it to the DoOutWork delegate instance. Inside the anonymous method body, the out variable s is assigned a value first (as it doesn't have one by definition as an out parameter), writes it to the console, and returns the string hash code.

 // Declare instance and assign method. DoOutWork dow = delegate(out string s) {     s = "WorkFinished";     Console.WriteLine(s);     return s.GetHashCode(); }; 

To run the anonymous method code, invoke the delegate with an out parameter and then print out the result to the console:

 // Invoke delegate. string work; int i = dow(out work); Console.WriteLine(work); 

To use the ref parameter modifier in an anonymous method, you create an inline method to hook up to the DoRefWork delegate with a ref parameter. In the method, you show you can write the original value out, reassign the value, and get the hash code of the new value:

 // Declare instance and assign method. DoRefWork drw = delegate(ref string s) {     Console.WriteLine(s);     s = "WorkFinished";     return s.GetHashCode(); }; 

To run the anonymous method, you assign a value to the string work and then pass it as a ref parameter to the DoRefWork delegate that is instantiated. Upon return from the delegate call, you write out the new value for the work string:

 // Invoke delegate. work = "WorkStarted"; i = drw(ref work); Console.WriteLine(work); 

Even though it is possible to declare a delegate with the params modifier, you cannot hook up the delegate using an anonymous method with the params keyword in the parameter list. You get the CS1670 "params is not valid in this context" compiler error on the DoParamsWork line.

 // "params is not valid in this context" //DoParamsWork dpw = delegate(params object[] workItems) //{ //    foreach (object o in workItems) //    { //        Console.WriteLine(o.ToString( )); //    } //    return o.GetHashCode( ); //}; 

You can, however, omit the params keyword and still call the delegate as shown here:

 // All we have to do is omit the params keyword. DoParamsWork dpw = delegate(string[] workItems) {     foreach (object o in workItems)     {         Console.WriteLine(o.ToString());     }     return workItems.GetHashCode(); }; 

Notice that although you've removed the params keyword from the anonymous method, this doesn't stop you from using the same syntax. The params keyword is present on the delegate type, so you can invoke it thusly:

 int i = dpw("Hello", "42", "bar"); 

So this illustrates that you can bind an anonymous method to a delegate declared using params, and once you've done that, you can call it passing in any number of parameters you like just as you'd expect.

Discussion

Anonymous methods cannot access the ref or out parameters of an outer scope. This means any out or ref variables that were defined as part of the containing method are off-limits for use inside the body of the anonymous method.

 // Declare delegate. delegate int DoWork(string work); public void TestOut(out string outStr) {     // Declare instance.     DoWork dw = delegate(string s)     {         Console.WriteLine(s);         // Causes error CS1628:         // "Cannot use ref or out parameter 'outStr' inside an         // anonymous method block"         //outStr = s;         return s.GetHashCode();     };     // Invoke delegate.     int i = dw("DoWorkMethodImpl1"); } public void TestRef(ref string refStr) {     // Declare instance.     DoWork dw = delegate(string s)     {         Console.WriteLine(s);         // Causes error CS1628:         // "Cannot use ref or out parameter 'refStr' inside an         // anonymous method block"         // refStr = s;         return s.GetHashCode();     };     // Invoke delegate     int i = dw("DoWorkMethodImpl1"); } 

Interestingly enough, anonymous methods can access outer variables with the params modifier.

 // Declare delegate. delegate int DoWork(string work); public void TestParams(params string[] items) {     // Declare instance.     DoWork dw = delegate(string s)     {         Console.WriteLine(s);         foreach (string item in items)         {             Console.WriteLine(item);         }         return s.GetHashCode();     };     // Invoke delegate.     int i = dw("DoWorkMethodImpl1"); } 

Since the params modifier is there for the benefit of the calling site (so the compiler knows to make this a method call that supports variable-length argument lists) and since anonymous methods are never called directly (always called via a delegate), then it makes no sense for an anonymous method to be decorated with something there for the benefit of the calling sitethere is no calling site. This is why it doesn't matter that you can't use the params keyword on an anonymous method. For anonymous methods, the calling site is always calling through the delegate, so what matters is whether that delegate has the params keyword or not.

See Also

See Recipe 9.12; see the "CS1670," "CS1628," "out," "ref," "params," and "System. ParamArrayAttribute" topics in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net