Most of the time a function needs information from the programmer to do its task. For example, if you write a function to add two numbers, the function needs to know what two numbers to add. To be able to pass information to the function, and sometimes to receive information from the function, programmers declare variables as part of the function declaration. These variables are called parameters. Parameters have a direction. The direction determines how the values are passed from the caller to the callee, and what information gets transmitted back from the callee to the caller. Parameters can have three different directions. These are: in (or by value), out, and in and out (by reference). By default parameters are "in" parameters. It can be difficult to understand how parameters are sent between the caller and a function, even to a seasoned developer. Before understanding the differences between in, ref, and out parameters you have to understand that the .NET Framework makes a distinction between two types of data types: value types and reference types. Value types refer to primitive types, such as byte, int, book, double, float, etc., (almost every common type except for string, which is a special type of reference type), structures and enums. Reference types include object, string, and any custom types you define as a class (more on this later). The meaning of in, ref and out changes slightly depending on whether you're using value types or reference types. First let's talk about using value types as parameters. Consider the code in Figure 2.33 . The x parameter in DoTask1 is an "in" parameter. (The absence of a direction modifier in front of the parameter. is what makes it an "in" parameter.) If you look at the code in DoTask1 you will notice that x can be set to a value. But the caller's variable, num , is unaffected by these changes. Also with "in" parameters you can send either a literal or a variable that has been set to a value. Figure 2.33 The receiving parameter only gets a copy of the original value. Changing the function's parameter has no effect on the value of the caller's variable.void DoTask1( int x ) { x = 20; //this statement only changes //a copy of the original //variable, not the original //variable } void ProgramCode() { DoTask1(5); //can send literal to //"in" parameter int num = 10; //the variable must be //set to a value //before calling DoTask1 DoTask1(num); Response.Write(num); //prints 10, //num is unchanged } Now look at the code in Figure 2.34 . The x parameter is a ref parameter, or in-out parameter. It has the ref modifier in front of the parameter. Notice that if the value of the parameter is changed inside DoTask2 , the original variable used, num , is also changed. With ref parameters you can't send literal values. You have to declare a variable and send the variable as the input for the parameter. Just like in the case of "in" parameters, you have to assign a value to the variable before using it. One main difference in the way you call the function is that you have to use ref in the call in front of the parameter. Figure 2.34 With ref parameters the receiving function doesn't get a copy; instead it gets the location in memory of the original value. Changing the ref variable also changes the value of the caller's variable.void DoTask2( ref int x ) { x = 20; //this statement changes the original variable } void ProgramCode() { DoTask2(ref 5); //*** illegal to send literal to ref //parameter int num = 10; //the variable must be set to a value //before calling DoTask2 DoTask2( ref num ); Response.Write(num); //prints 20, num changed } Now look at Figure 2.35 . Out parameters are similar to ref parameters in that when you change the value inside the function the original variable used is also changed. One difference is that when a function has an out parameter, it is assumed that the function will provide the value not the caller. Therefore, the compiler gives you an error if you forget to assign a value to the out parameter. You have to use the keyword out in front of the parameter you're sending. With out parameters you can't send literal values. Another difference from ref parameters is that you don't have to assign a value to the variable you're sending as a parameter. Figure 2.35 Out parameters are like ref parameters except that with out parameters the caller's variable doesn't have to be initialized beforehand; the value must be provided by the function.void DoTask3( out int x ) { x = 20; //with out parameters you are //required to assign a value //to x. } void ProgramCode() { DoTask3(out 5); //*** illegal to send //literal to out //parameter int num; //num does not have to //be initialized and //if it is the value //is ignored. DoTask3(out num); Response.Write(num); //prints 20, num //is changed } Things are a little different when using reference types (classes) instead of value types as parameter types. However, there are a few concepts to learn before being able to talk about reference types being used as parameters. At the end of this chapter we will revisit the topic of parameter direction and talk about how things change with reference parameters. To declare parameters:
Tips
|