To begin, you will reexamine System.Console.Write(), System.Console.WriteLine(), and System.Console.ReadLine() from Chapter 1. This time, look at them as examples of method calls in general, instead of looking at the specifics of printing and retrieving data from the console. Listing 4.2 shows each of the three methods in use. Listing 4.2. A Simple Method Call
The parts of the method call include the namespace, type name, method name, parameters, and return data type. A period separates each part of a fully qualified method name. NamespaceThe first item in the method call is the namespace. The namespace is a categorization mechanism for grouping all types related to a particular set of functionality. The namespace helps avoid type name collisions. For example, the compiler can distinguish between two types with the name "Program" as long as each type has a different namespace. The result is that the Main method in each class could be referred to using Awl.Windows.Program.Main() or Awl.Console.Program.Main(). System.Collections, System.Collections.Generics, System.IO, and System.Runtime.Serialization.Formatters are valid names for a namespace. Namespaces can include periods within their names. This enables the namespaces to give the appearance of being hierarchical. This improves human readability only, since the compiler treats all namespaces at a single level. For example, System.Collections.Generics appears within the System.Collections namespace hierarchy, but to the compiler these are simply two entirely different namespaces. In Listing 4.2, the namespace for the Console type is System. The System namespace contains the types that enable the programmer to perform many fundamental programming activities. Virtually all C# programs use types within the System namespace. Table 4.1 provides a listing of other common namespaces.
It is not always necessary to provide the namespace when calling a method. For example, if you call a method in the same namespace as the target method, then the compiler can infer the namespace to be the same as the caller's namespace. Later in this chapter, you see how the using directive avoids the need for a namespace qualifier as well. Type NameCalls to static methods (Chapter 5 covers static versus instance methods) require the type name qualifier as long as the target method is not within the same class (such as a call from HelloWorld.Main() to Console.WriteLine()). However, just as with the namespace, C# allows the elimination of the type name from a method call whenever the method is available on the containing type. (Examples of method calls like this appear in Listing 4.4.) The type name is unnecessary because the compiler infers the type from the calling method. If the compiler can make no such inference, the name must provided as part of the method call. At their core, types are a means of grouping together methods and their associated data. For example, Console is the type name that contains the Write(), WriteLine(), and ReadLine() methods (among others). All of these methods are in the same "group" because they belong to the Console type. ScopeYou already learned that scope bounds declaration and accessibility. Scope also defines the inferred call context. A method call between two methods in the same namespace does not require the namespace qualifier. Similarly, two calls within the same class do not require the type name because the scope is the same. Method NameAfter specifying which type contains the method you wish to call, it is time to identify the method itself. C# always uses a period between the type name and the method name, and a pair of parentheses following the method name. Between the parentheses may appear any parameters that the method requires. ParametersAll methods have from zero to n parameters, and each parameter in C# is of a specific data type. For example, the following method call, used in Listing 4.2, has three parameters: System.Console.WriteLine( "Your full name is {1} {0}",lastName, firstName) The first is a string and the second two are of type object. Although you pass parameter values of type string for the second two parameters as well, the compiler allows this because all types, including string, are compatible with the data type object. Method ReturnIn contrast to System.Console.WriteLine(), System.Console.ReadLine() in Listing 4.2 does not have any parameters. However, this method happens to have a method return. The method return is a means of transferring results from a called method back to the caller. Because System.Console.ReadLine() has a return, it is possible to assign the return value to the variable firstName. In addition, it is possible to pass this method return as a parameter, as shown in Listing 4.3. Listing 4.3. Passing a Method Return As a Parameter to Another Method Call
Instead of assigning a variable and then using it in the call to System.Console.WriteLine(), Listing 4.3 calls the System.Console.ReadLine() method within the call to System.Console.WriteLine(). At execution time, the System.Console.ReadLine() method executes first and its return is passed directly into the System.Console.WriteLine() method, rather than into a variable. Not all methods return data. Both versions of System.Console.Write() and System.Console.WriteLine() are examples of such methods. As you will see shortly, these methods specify a return type of void just as the HelloWorld declaration of Main returned void. Statement versus Method CallListing 4.3 provides a demonstration of the difference between a statement and a method call. Although System.Console.WriteLine("Hello {0}!",System.Console.ReadLine()); is a single statement, it contains two method calls. A statement generally contains one or more expressions, and in this example, each expression is a method call. Therefore, method calls form parts of statements. Although coding multiple method calls in a single statement often reduces the amount of code, it does not necessarily increase the readability and seldom offers a significant performance advantage. Developers should favor readability over brevity. |