7.2 Method basics


I shall cover method structure and method parameters before going into other aspects of methods .

7.2.1 Method structure

A C# method is structured in the same way as a Java method: [1]

[1] The textbook definition of 'method signature' in C# comprises only of the method identifier (the name ) and the type and kind (reference, value or output) of its parameters. All modifiers and the method's return type are not considered to be part of the method signature. The params keyword, if used in the parameter list, is also not part of the signature.

 [assess_modifier][other_modifiers] return_type method_name ([parameter(s)]){   //method code } 

For example, the method:

 private void DoThis (int j, string s, object o){ } 

takes in three parameters “ an int object, a string object, and an object object “ and returns nothing. This method has private access protection, so that it can only be invoked from with the same class.

Unlike Java
  • Remember that if the access modifier is omitted, C#'s default access level is private .

  • The return type and parameter type(s) of a method must be at least as accessible as the method itself.

    The following code compiles:

     1: class B{} 2: 3: class A{ 4:   public B DoSomething(){ // method returns type B 5:     return new B(); 6:   } 7: } 

    However, just by changing the accessibility of class A to public , as shown below (line 3), a compilation error occurs:

     1: class B{} 2: 3:  public  class A{ 4:   public B DoSomething(){ 5:    return new B(); 6:   } 7: } 

    Compilation error:

     test.cs(4,12): error CS0050: Inconsistent accessibility: return type 'B' is less accessible than method 'A. DoSomething()' 

    The reason for this is by making A a public class, the accessibility of DoSomething() is now weaker (less strict) than the return type (class B). This violates the rule under discussion.

7.2.2 Method parameters

There are some differences between Java and C# where method parameters are concerned . [2]

[2] C/C++ programmers who love to pass pointers and references using * s and &s will realize that C#, like Java, has got rid of such messy stuff. Unless you are writing C# unsafe codes, there will be no more passing the-address-of-the-address of that integer variable over to a method, or performing deferencing n -levels down to get your value. Personally, I view this as a change for the better and am eternally grateful. Java developers who have never done C/C++ before (and hence do not understand what I am talking about here) well, just be thankful.

In Java, if you pass a primitive variable (or variable of simple/primitive type) to a method, the original primitive variable's value in the calling method will not be affected. Only a copy of the value stored in the calling method's primitive variable is being sent over. The output of the following Java program demonstrates that simple types are 'passed by value':

 1: // Test.java  2: public class Test{  3:   public static void main(String args[]){  4:     int a=0;  5:     Test.doSomething(a);  6:     System.out.println(a);  7:   }  8:   static void doSomething(int y){  9:     y=99; //does not affect calling method's variable 10:   } 11: } 

Output:

 c:\expt>java Test 0 

The same thing happens with C# when you pass over a value type [3] object. Examine the output of this C# program:

[3] The C# specification uses the term 'simple type' to refer to a primitive type. As far as this book is concerned, the terms 'primitive type' and 'simple type' are synonyms “ they all refer to types such as int , long , float , double , etc. However the term 'value type' has a special meaning in C#. A 'value type' in C# includes all simple/primitive types and some other special types in C# (enum types and struct types, which will be covered in Chapters 25 and 26, respectively). A simple type is a subset of value type. The term 'value type' does not make sense in Java simply because there are no enums and structs in Java. Hence, as far as this discussion is concerned ( especially if you are unsure about what enums and structs are) just remember that the term value types encompasses all simple types. (So much for techno-jumbo “ get more of it in Chapter 9.) Furthermore, don't be surprised to see me use the term 'value type object' or 'value object' because, in C#, even your int s, long s and float s can be treated as objects and will be converted into objects when necessary automatically.

 1: // Test.cs  2: public class Test{  3:   public static void Main(){  4:     int a=0;  5:     Test.DoSomething(a);  6:     System.Console.WriteLine(a);  7:   }  8:   static void DoSomething(int y){  9:     y=99; 10:   } 11: } 

Output:

 c:\expt>test 0 

7.2.3 The ref keyword

Unlike Java, in C#, you can pass a value object by reference instead of by value.

If you want to pass value type a over to method DoSomething , such that DoSomething is able to permanently change the value stored in a of the calling method, C# provides two keywords, ref and out . We shall study ref first.

All you need to do is to insert in the ref keyword in the method invocation statement, and the method signature of DoSomething() :

 1: // Test.cs  2: public class Test{  3:   public static void Main(){  4:     int a = 0; // a is initialized  5:     Test.DoSomething(  ref  a);  6:     System.Console.WriteLine(a);  7:   }  8:   static void DoSomething(  ref  int y){  9:     y=99; 10:   } 11: } 

Output:

 c:\expt>test 99 

The ref keyword passes a reference to the actual int object over to the invoked method so that its value can be altered there directly. In Java, there is no way you can 'pass by reference' a primitive type to a method “ primitive types will always be passed 'by value'.

7.2.4 The out keyword

The keyword out is identical to ref , except for one difference “ before you pass over a value type variable using ref , that variable must already have been initialized with a value. However, when you pass a variable over using out , it is not necessary for it to be initialized with a value.

The previous code example works well if you replace ref with out on lines 5 and 8 “ out doesn't care if a has already been initialized with a value.

But the ref keyword does care. Let's alter line 4 so that a is not given a value.

 1: // Test.cs  2: public class Test{  3:   public static void Main(){  4:  int a;  // a is not initialized  5:     Test.DoSomething(  ref a  );  6:     System.Console.WriteLine(a);  7:   }  8:   static void DoSomething(  ref  int y){  9:     y=99;  10:  }  11: } 

Output:

 c:\expt>test Test.cs(5,26): error CS0165: Use of unassigned local variable 'a' 

A runtime error occurs because a has not been initialized with a value before being 'handed over' to DoSomething .

Just think of out as a more lenient alternative of ref . You must ensure that variables passed over using ref are assigned a value first. For out , it doesn't matter. [4]

[4] ref is useful if the called method will use the value stored in the passed-over variable. If you use out , the called method will then have to perform manual checks to see if the variable has been initialized with a value.

7.2.5 Passing object references

Passing method parameters by ref and out apply only to the passing of value types such as int , bool , double, etc. In both Java and C#, passing a reference type actually passes the address of the object being referenced over to the invoked method.

Any alterations to the object in the called method are permanent, since the alterations are performed on the actual object itself. The C# example below demonstrates this.

 1: public class Test{  2:   int i;  3:  4:   public static void Main(){  5:     Test t = new Test();  6:     t.i = 0;  7:     Test.DoSomething(t);  8:     System.Console.WriteLine(t.i);  9:  } 10:  static void DoSomething(Test z){ 11:    z.i=99; 12:  } 13: } 

Output:

 c:\expt>test 99 


From Java to C#. A Developers Guide
From Java to C#: A Developers Guide
ISBN: 0321136225
EAN: 2147483647
Year: 2003
Pages: 221
Authors: Heng Ngee Mok

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