Tuesday, 5 April 2016

Out, Ref and Params keyword in .NET

The Out Keyword:

The out keyword causes arguments to be passed by reference. This is like the ref keyword, except that ref requires that the variable be initialized before it is passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword. For example:

C#

class OutDemo

{

    static void Method(out int i)

    {

        i = 65;

    }



    static void Main()

    {

        int value;

        Method(out value);

        // value is now 65

    }
}

Although variables passed as out arguments do not have to be initialized before being passed, the called method is required to assign a value before the method returns.

Although the ref and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. Therefore, methods cannot be overloaded if the only difference is that one method takes a ref argument and the other takes an out argument. The following code, for example, will not compile

class ExampleClass
{
    // Compiler error ExampleClass: "Cannot define overloaded  
    // methods that differ only on ref and out". 
    public void SampleMethod(out int i) { i = 23;  }
    public void SampleMethod(ref int i) { }
}

Overloading can be done, however, if one method takes a ref or out argument and the other uses neither, like this:

class OutOverloadDemo
{
    public void SampleMethod(int i) { }
    public void SampleMethod(out int i) { i = 7; }
}

Properties are not variables and therefore cannot be passed as out parameters.
You can't use the ref and out keywords for the following kinds of methods:
·         Async methods, which you define by using the async modifier.
·         Iterator methods, which include a yield return or yield break statement.


Declaring an out method is useful when you want a method to return multiple values. The following example uses out to return three variables with a single method call. Note that the third argument is assigned to null. This enables methods to return values optionally.

class OutReturnExample
    {
        static void Method(out int i, out string s1, out string s2)
        {
            i = 96;
            s1 = "s1 I'll be retruned";
            s2 = null;
        }

        static void Main()
        {
            int value;
            string str1, str2;
            Method(out value, out str1, out str2);
            // value is now 96
            // str1 is now "s1 I'll be returned" 
            // str2 is (still) null;
        }
    }




The Ref Keyword:

Pass a ref if you want to change what the object is:

   class TestRef
    {
TestRef objTestRefClass = null;
        public string WriteSomeThing = string.Empty;
        public void DoSomeThing(ref TestRef t)
        {
            objTestRefClass = new TestRef();
            t.WriteSomeThing = "Not just a changed objTestRefClass, but a completely different TestRef object";
            Console.WriteLine(t.WriteSomeThing);
        }
    }
class OutReturnExample
    {
       
        static void Main()
        {
            TestRef objTestRef  = new TestRef();
           objTestRef.WriteSomeThing = "Foo";
           objTestRef.DoSomeThing(ref objTestRef);
            Console.ReadKey();

        }
    }




After calling DoSomething, objTestRef does not refer to the original 'new TestRef', but refers to a completely different object.


This may be useful too if you want to change the value of an immutable object, eg a string. You can't change the value of a string once it has been created (use StringBuilder for this purpose instead), but by using a ref, you could create a function that changes the string for another one that has a different value.

It is not a good idea to use ref unless it is needed. Using ref gives the method freedom to change the argument for something else, callers of the method will need to to be coded to ensure they handle this possibility.

When the parameter type is an object, then object variables always act as references to the object. This means, when the ref keyword is used you've got a reference to a reference. This allows you to do things as described in the example given above. But, when the parameter type is a primitive value (eg int), then if this parameter is assigned to within the method, the value of the argument that was passed in will be changed after the method returns.



The Params Keyword in .NET:



By using the params keyword, you can specify a method parameter that takes a variable number of arguments.

You can send a comma-separated list of arguments of the type specified in the parameter declaration or an array of arguments of the specified type. You also can send no arguments. If you send no arguments, the length of the params list is zero.
No additional parameters are permitted after the params keyword in a method declaration, and only one params keyword is permitted in a method declaration.

static void Main(string[] args)
        {
            abc a=new abc ();
            a.parmsKeyWord1(5,"a","aaaa","w");

            a.parmsKeyWord2(4,"null",""," ",'c',"good",45.6);
            a.parmsKeyWord2();
            Console.WriteLine("Press any key to continue...");

            a.parmsKeyWord2();
            Console.ReadKey();
        }

        public class abc
        {
            internal void parmsKeyWord1(int a, params string[] sentence)
            {
                foreach (var item in sentence)
                {
                    Console.WriteLine("Items = " + item);
                }
            }

            internal void parmsKeyWord2( params object[] sentence)
            {
                //Console.WriteLine("This is only for test purpose...1");
                //if (sentence[0]=="")
                //{
                //    Console.WriteLine("This is empty parameter call");
                //}
                //else
                //{
                    foreach (var item in sentence)
                    {
                        Console.WriteLine("Items = " + item);
                        //Console.WriteLine("This is only for test purpose...2");
                    }
                //}
            }
        }



(Practice Makes a Man Perfect)

No comments: