- 7.1 Introduction
- 7.2 Packaging Code in C#
- 7.3 static Methods, static Variables and Class Math
- 7.4 Methods with Multiple Parameters
- 7.5 Notes on Using Methods
- 7.6 Argument Promotion and Casting
- 7.7 The .NET Framework Class Library
- 7.8 Case Study: Random-Number Generation
- 7.9 Case Study: A Game of Chance; Introducing Enumerations
- 7.10 Scope of Declarations
- 7.11 Method-Call Stack and Activation Records
- 7.12 Method Overloading
- 7.13 Optional Parameters
- 7.14 Named Parameters
- 7.15 C# 6 Expression-Bodied Methods and Properties
- 7.16 Recursion
- 7.17 Value Types vs. Reference Types
- 7.18 Passing Arguments By Value and By Reference
- 7.19 Wrap-Up
7.6 Argument Promotion and Casting
Another important feature of method calls is argument promotion—implicitly converting an argument’s value to the type that the method expects to receive (if possible) in its corresponding parameter. For example, an app can call Math method Sqrt with an integer argument even though the method expects to receive a double argument. The statement
Console.WriteLine(Math.Sqrt(4));
correctly evaluates Math.Sqrt(4) and displays the value 2.0. Sqrt’s parameter list causes C# to convert the int value 4 to the double value 4.0 before passing the value to Sqrt. Such conversions may lead to compilation errors if C#’s promotion rules are not satisfied. The promotion rules specify which conversions are allowed—that is, which conversions can be performed without losing data. In the Sqrt example above, an int is converted to a double without changing its value. However, converting a double to an int truncates the fractional part of the double value—thus, part of the value is lost. Also, double variables can hold values much larger (and much smaller) than int variables, so assigning a double to an int can cause a loss of information when the double value doesn’t fit in the int. Converting large integer types to small integer types (e.g., long to int) also can produce incorrect results.
7.6.1 Promotion Rules
The promotion rules apply to expressions containing values of two or more simple types and to simple-type values passed as arguments to methods. Each value is promoted to the appropriate type in the expression. (Actually, the expression uses a temporary copy of each promoted value—the types of the original values remain unchanged.) Figure 7.3 lists the simple types alphabetically and the types to which each can be promoted. Values of all simple types also can be implicitly converted to type object. We demonstrate such implicit conversions in Chapter 19.
Fig. 7.3 | Implicit conversions between simple types.
7.6.2 Sometimes Explicit Casts Are Required
By default, C# does not allow you to implicitly convert values between simple types if the target type cannot represent every value of the original type (e.g., the int value 2000000 cannot be represented as a short, and any floating-point number with nonzero digits after its decimal point cannot be represented in an integer type such as long, int or short).
To prevent a compilation error in cases where information may be lost due to an implicit conversion between simple types, the compiler requires you to use a cast operator to force the conversion. This enables you to “take control” from the compiler. You essentially say, “I know this conversion might cause loss of information, but for my purposes here, that’s fine.” Suppose you create a method Square that calculates the square of an int argument. To call Square with the whole part of a double argument named doubleValue, you’d write Square((int) doubleValue). This method call explicitly casts (converts) the value of doubleValue to an integer for use in method Square. Thus, if doubleValue’s value is 4.5, the method receives the value 4 and returns 16, not 20.25.