Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
11 views120 pages

ClassesAndObjects A DeeperLook

The document discusses class design in C#, focusing on the Time1 and Time2 classes, their properties, methods, and constructors. It emphasizes the importance of encapsulation, exception handling, and the use of the 'this' keyword for referencing instance variables. Additionally, it covers concepts such as composition, operator overloading, and the use of the nameof operator for error messaging.

Uploaded by

deoneleboda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views120 pages

ClassesAndObjects A DeeperLook

The document discusses class design in C#, focusing on the Time1 and Time2 classes, their properties, methods, and constructors. It emphasizes the importance of encapsulation, exception handling, and the use of the 'this' keyword for referencing instance variables. Additionally, it covers concepts such as composition, operator overloading, and the use of the nameof operator for error messaging.

Uploaded by

deoneleboda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 120

A Deeper Look

◙ Use composition to allow a class to have references to objects of other


classes as members
◙ Throw an exception to indicate that an argument is out of range
◙ Enable an object to refer to itself with the keyword this
◙ Use static variables and methods
◙ Use readonly fields
◙ Take advantage of C#’s memory-management features
◙ Use the IDE’s Class View and Object Browser windows
◙ Use object initializers to create an object and initialize it in the same
statement
◙ Overload built-in operators to work with objects of your own types
◙ Define your own value type with struct
◙ Use extension methods to enhance an existing class’s capabilities
2
◙ Class Time1 (Figure-1) represents the time of day
◙ The class contains public properties for the Hour, Minute
and Second
◙ A class’s public members are the public services or the
public interface that this class provides to its clients
◙ Time1 does not declare a constructor, so the compiler defines a
default constructor
◙ Each property receives the default value 0 for an int
◙ Instance variables and auto‐implemented properties also
can be assigned values in their declarations
3
Time1 Class Declaration Maintains the
Time in 24-Hour Format (1 of 3)

Figure-1: Time1 class declaration maintains the time in 24-hour format (1 of 3) 4


Time1 Class Declaration Maintains the
Time in 24-Hour Format (2 of 3)

Figure-1: Time1 class declaration maintains the time in 24-hour format (2 of 3) 5


Time1 Class Declaration Maintains the
Time in 24-Hour Format (3 of 3)

Figure-1: Time1 class declaration maintains the time in 24-hour format (3 of 3) 6


public Class
◙ Time1 is a public class—it can potentially be reused in other
projects
◙ When a class is declared as public, then that class could be
reused in another project

7
Method SetTime and Throwing Exceptions
◙ Method SetTime is a public method that declares three int
parameters and uses them to set the time
◙ Lines 16–17 test each argument to determine whether the
value is out of range. If not, lines 22–24 assign values to the
properties
◙ The hour value must be greater than or equal to 0 and less than
24, because universal‐time format represents hours as
integers from 0 to 23 (e.g., 1 PM is hour 13 and 11 PM is hour
23; midnight is hour 0 and noon is hour 12)
8
◙ Both minute and second values must be greater than or equal
to 0 and less than 60
◙ For values outside these ranges, SetTime throws an
ArgumentOutOfRangeException, which notifies the client
code that an invalid argument was passed to the method
◙ The throw statement creates a new object of type
ArgumentOutOfRangeException
◙ The parentheses following the class name indicate a call to the
ArgumentOutOfRangeException constructor

9
◙ After the exception object is created, the throw statement
immediately terminates method SetTime and the exception is
returned to the code that attempted to set the time

10
Method ToUniversalString
◙ Method ToUniversalString is an expression-bodied method
◙ The method takes no arguments and returns a string in
universal-time format, consisting of six digits—two for the
hour, two for the minute and two for the second
◙ The D2 format specifier formats an integer with two digits and,
where needed, a leading 0 if the integer has fewer than two
digits

11
Method ToString
◙ Method ToString (lines 32–34) is an expression-bodied
method
◙ Method ToString takes no arguments and returns a string
in standard‐time format, in which the Hour, Minute and
Second values are separated by colons and followed by an AM
or PM indicator (e.g., 1:27:06 PM)

12
◙ The Time1Test app class (Figure-2) uses class Time1

13
Time1 Object Used in an App (1 of 3)

Figure-2: Time1 object used in an app (1 of 3)12.8 14


Time1 Object Used in an App (2 of 3)

Figure-2: Time1 object used in an app (2 of 3) 15


Time1 Object Used in an App (3 of 3)

Figure-2: Time1 object used in an app (3 of 3) 16


Notes on the Time1 Class Declaration
◙ Consider several class-design issues with respect to class Time1
◘ The time is represented as three integers for the hour, minute and
second
◘ The actual data representation used within the class is of no concern
to the class’s clients
◘ It would be perfectly reasonable for Time1 to represent the time
internally as the number of seconds since midnight or the number of
minutes and seconds since midnight
◘ Clients could use the same public methods and properties to get the
same results without being aware of this
◘ The Hour, Minute and Second properties would need to be
reimplemented to work with the new data representation
17
◙ Classes simplify programming because the client can use only
the public members exposed by the class
◙ Such members are usually client oriented rather than
implementation oriented
◙ Clients are neither aware of, nor involved in, a class’s
implementation
◙ Clients generally care about what the class does but not how
the class does it
◙ Clients do, of course, care that the class operates correctly and
efficiently
18
Interfaces change less frequently than implementations. When an
implementation changes, implementation-dependent code must
change accordingly
Hiding the implementation reduces the possibility that other
parts of the app become dependent on class-implementation
details

19
Date and time manipulations are more complex than the
simplified classes we use in the previous example
For applications that require date and time processing, check out
.NET’s DateTimeOffest, DateTime, TimeSpan and
TimeZoneInfo value types in namespace System

20
◙ The access modifiers public and private control access to a
class’s variables, methods and properties
◙ The primary purpose of public methods/properties is to
present to the class’s clients a view of the services the class
provides
◘ Clients of the class need not be concerned with how the class
accomplishes its tasks
◙ A class’s private variables, properties and methods are not
directly accessible to the class’s clients

21
◙ Figure-3 demonstrates that private class members are not
directly accessible outside the class
◙ In this app, we use a modified version of class Time1 that
declares private instance variables hour, minute and
second, rather than public properties Hour, Minute and
Second
◙ Members of a class—for instance, properties, methods and
instance variables—have private access by default

22
Private Members of Class Time1 are Not
Accessible Outside the Class

Figure-3: Private members of class Time1 are not accessible outside the class 23
◙ Every object can access a reference to itself with keyword this
◙ When a non-static method/property is called, its body
implicitly uses keyword this to refer to the object’s instance
variables and other non-static class members
◙ As you will see in Figure-4, you can also use keyword this
explicitly in a non-static method’s body

24
this used Implicitly and Explicitly to
Refer to Members of an Object (1 of 3)

Figure-4: this used implicitly and explicitly to refer to members of an object (1 of 3) 25


this used Implicitly and Explicitly to
Refer to Members of an Object (2 of 3)

Figure-4: this used implicitly and explicitly to refer to members of an object (2 of 3) 26


this used Implicitly and Explicitly to
Refer to Members of an Object (3 of 3)

Figure-4: this used implicitly and explicitly to refer to members of an object (3 of 3) 27


◙ If the constructor’s parameter names are identical to the class’s
instance-variable names, so they hide (shadow) the
corresponding instance variables
◙ You can use the this reference to refer to hidden instance
variables explicitly
◙ If a member is not hidden, the this keyword is implied, but
can be included explicitly

28
Using properties throughout a class to access the class’s instance
variables normally eliminates shadowing because property
names use Pascal Case naming (capital first letter) and
parameter names use Camel Case (lowercase first letter)

29
◙ Overloaded constructors enable objects of a class to be
conveniently initialized in different ways
◙ To overload constructors, simply provide multiple constructor
declarations with different signatures

30
◙ Class Time2 (Figure-5) contains overloaded constructors

31
Time2 Class Declaration
with Overloaded Constructors (1 of 6)

Figure-5: Time2 class declaration with overloaded constructors (1 of 6) 32


Time2 Class Declaration
with Overloaded Constructors (2 of 6)

Figure-5: Time2 class declaration with overloaded constructors (2 of 6) 33


Time2 Class Declaration
with Overloaded Constructors (3 of 6)

Figure-5: Time2 class declaration with overloaded constructors (3 of 6) 34


Time2 Class Declaration
with Overloaded Constructors (4 of 6)

Figure-5: Time2 class declaration with overloaded constructors (4 of 6) 35


Time2 Class Declaration
with Overloaded Constructors (5 of 6)

Figure-5: Time2 class declaration with overloaded constructors (5 of 6) 36


Time2 Class Declaration
with Overloaded Constructors (6 of 6)

Figure-5: Time2 class declaration with overloaded constructors (6 of 6) 37


Class Time2’s Three-Argument Constructor
◙ Lines 12–15 declare a constructor with three default
parameters
◙ This is also the class’s parameterless constructor because
you can call the constructor without arguments and the
compiler will automatically provide the default parameter
values

38
◙ A constructor can call methods of its class
◙ Be aware that the instance variables might not yet be
initialized, because the constructor is in the process of
initializing the object
◙ Using instance variables before they have been initialized
properly is a logic error

39
◙ Using this as in line 19
: this(time.Hour, time.Minute, time.Second) { }
is called a constructor initializer
◙ Use of this keyword, enables a class to reuse initialization
code provided by a constructor, rather than defining similar
code in another constructor

40
Constructor initializers make classes easier to maintain, modify
and debug, because the common initialization code can be
defined in one constructor and called by others

41
Notes Regarding Class Time2’s Methods, Properties
and Constructors
◙ Consider changing the representation of the time to a single
int value representing the total number of seconds that have
elapsed since midnight
◘ Only the bodies of the methods that access the private data directly
would need to change
◘ There would be no need to modify the bodies of methods SetTime,
ToUniversalString or ToString
◙ When there is no access modifier before a get or set accessor,
the accessor inherits the access modifier preceding the
property name 42
◙ It’s common to include in an exception’s error message a
variable’s or property’s identifier
◘ Can help a client-code programmer understand the context in which
the exception occurred
◙ Prior to C# 6, you had to hard code these identifiers into your
error-messages
◙ As of C# 6, you can instead use the nameof operator, which
returns a string representation of the identifier enclosed in
parentheses

43
When executing a method of a class, if that method has a
reference to another object of the same class (typically received
via a parameter), the method can access all of that other object’s
data and methods (including those that are private)

44
When you need to include an identifier in a string literal, use
the nameof operator rather than hard coding the identifier’s
name in the string
If you right click an identifier in Visual Studio then use the
Rename… option to change the identifier’s name throughout your
code, the string that nameof returns will be updated
automatically with the identifier’s new name

45
When implementing a method of a class, using the class’s
properties to access the class’s private data simplifies code
maintenance and reduces the likelihood of errors

46
◙ Class Time2Test (Figure-6) creates six Time2 objects to
invoke the overloaded Time2 constructors

47
Overloaded Constructors used to
Initialize Time2 Objects (1 of 4)

Figure-6: Overloaded constructors used to initialize Time2 objects (1 of 4) 48


Overloaded Constructors Used to
Initialize Time2 Objects (2 of 4)

Figure-6: Overloaded constructors used to initialize Time2 objects (2 of 4) 49


Overloaded Constructors Used to
Initialize Time2 Objects (3 of 4)

Figure-6: Overloaded constructors used to initialize Time2 objects (3 of 4) 50


Overloaded Constructors Used to
Initialize Time2 Objects (4 of 4)

Figure-6: Overloaded constructors used to initialize Time2 objects (4 of 4) 51


◙ Every class must have at least one constructor
◙ If you do not provide any constructors in a class’s declaration,
the compiler creates a default constructor that takes no
arguments when it is invoked
◙ The compiler will not create a default constructor for a class
that explicitly declares at least one constructor
◙ If you have declared a constructor, but want to be able to
invoke the constructor with no arguments, you must declare a
parameterless constructor

52
◙ A class can have objects of values types or references to objects
of other classes as members
◙ This is called composition and is sometimes referred to as a
has‐a relationship

53
◙ One form of software reuse is composition, in which a class
contains references to other objects
◙ Recall that classes are reference types
◙ A class can have a property of its own type—for example, a
Person class could have Mother and Father properties of
type Person that reference other Person objects

54
◙ Class Date (Figure-7) declares instance variables month and
day, and auto-implemented property Year (line 9) to
represent a date

55
Date Class Declaration (1 of 4)

Figure-7: Date class declaration (1 of 4) 56


Date Class Declaration (2 of 4)

Figure-7: Date class declaration (2 of 4) 57


Date Class Declaration (3 of 4)

Figure-7: Date class declaration (3 of 4) 58


Date Class Declaration (4 of 4)

Figure-7: Date class declaration (4 of 4) 59


◙ Class Employee (Figure-8)
◘ has public auto-implemented, read-only properties FirstName,
LastName, BirthDate and HireDate
◘ demonstrates that a class can have references to objects of other
classes as members

60
Employee Class with References to Other
Objects

Figure-8: Employee class with references to other objects 61


◙ Class EmployeeTest (Figure-9) creates two Date objects to
represent an Employee’s birthday and hire date, respectively

62
Figure-9: Composition demonstration 63
◙ Every object you create uses various system resources, such as
memory
◙ In many programming languages, these system resources are
reserved for the object’s use until they’re explicitly released by
the programmer
◙ If all the references to the object that manages the resource are
lost before the resource is explicitly released, it can no longer
be released. This is known as a resource leak

64
◙ The Common Language Runtime (CLR) uses a garbage
collector to reclaim the memory occupied by objects that are
no longer in use
◙ When there are no more references to an object, the object
becomes eligible for destruction
◙ Every object has a destructor that’s invoked by the garbage
collector to perform termination housekeeping before its
memory is reclaimed

65
◙ A destructor’s name is the class name, preceded by a tilde, and
it has no access modifier in its header
◙ After an object’s destructor is called, the object becomes
eligible for garbage collection—the memory for the object
can be reclaimed by the garbage collector
◙ Memory leaks are less likely in C# than languages like C and
C++ (but some can still happen in subtle ways)

66
◙ Other types of resource leaks can occur, for example if an app
fails to close a file that it has opened
◙ A problem with the garbage collector is that it is not
guaranteed to perform its tasks at a specified time. For this
reason, destructors are rarely used

67
A class that uses resources, such as files on disk, should provide a
method to eventually release the resources
Many Framework Class Library classes provide Close or
Dispose methods for this purpose
Close methods are typically used with objects that are associated
with files and other types of so-called streams of data

68
◙ A static variable or property is used when only one copy of a
particular variable should be shared by all objects of a class
◙ A static variable or property represents classwide
information—all objects of the class share the same piece of
data
◙ The declaration of a static variable or property begins with
the keyword static

69
Use a static variable when all objects of a class must share the
same copy of the variable

70
◙ The scope of a static variable is the body of its class
◙ A class’s public static members can be accessed by
qualifying the member name with the class name and the
member access (.) operator, as in Math.PI
◙ A class’s private static class members can be accessed
only through the class’s methods and properties
◙ To access a private static member from outside its class,
a public static method or property can be provided

71
It’s a compilation error to access or invoke a static member by
referencing it through an instance of the class, like a non-static
member

72
static variables, methods and properties exist, and can be used,
even if no objects of that class have been instantiated
static members are available as soon as the class is loaded into
memory at execution time

73
◙ A static method (or property) cannot access non-static
class members directly, because a static method (or
property) can be called even when no objects of the class exist
◙ For the same reason, this cannot be used in a static
method—the this reference always refers to a specific object
of the class
◙ When a static method is called, it does not know which
object to manipulate and there might not be any objects of its
class in memory

74
◙ Class Employee declares public static auto-implemented
property Count to maintain a count of the number of
Employee objects that have been created
◙ Count’s set accessor is private, because only class
Employee should be able to modify Count’s value
◙ Count is a static auto-implemented property, so the
compiler creates a corresponding private static variable
that Count manages
◙ When you declare a static variable and do not initialize it, the
compiler initializes it to the type’s default value (in this case, 0)
75
Figure-10: static property used to maintain a count of the number of Employee objects that have been created 76
◙ Actually, string objects in C# are immutable—they cannot
be modified after they’re created. Therefore, it’s safe to have
many references to one string. This is not normally the case
for objects of most other classes
◙ If string objects are immutable, you might wonder why we’re
able to use operators + += to concatenate strings
◙ String concatenation operations actually result in a new
string object containing the concatenated values. The
original string objects are not modified

77
Figure-11: static member demonstration (1 of 2) 78
Figure-11: static member demonstration (2 of 2) 79
◙ The principle of least privilege states that code should be
granted the amount of privilege and access needed to accomplish
its designated task, but no more
◙ Constants declared with const must be initialized to a
constant value when they’re declared
◙ C# provides keyword readonly to specify that an instance
variable of an object is not modifiable and that any attempt to
modify it after the object is constructed is an error
◙ A readonly variable’s identifier uses Pascal case by
convention
80
◙ Although readonly instance variables can be initialized when
they’re declared, this is not required
◙ A readonly variable should be initialized by each of the
class’s constructors or in the variable’s declaration
◙ Each constructor can assign values to a readonly instance
variable multiple times—the variable doesn’t become
unmodifiable until after the constructor completes execution
◙ If a constructor does not initialize the readonly variable, the
variable uses the same default value as any other instance
variable
81
Declaring an instance variable as readonly helps enforce the
principle of least privilege. If an instance variable should not be
modified after the object is constructed, declare it to be
readonly to prevent modification

82
◙ const members must be assigned values at compile time
◙ const members can be initialized only with other constant
values, such as integers, string literals, characters and other
const members
◙ Constant members with values that cannot be determined at
compile time—such as constants that are initialized with the
result of a method call—must be declared with keyword
readonly, so they can be initialized at execution time
◙ Variables that are readonly can be initialized with more
complex expressions, such as an array initializer or a method
call that returns a value or a reference to an object 83
Attempting to modify a readonly instance variable anywhere
but in its declaration or the object’s constructors is a compilation
error

84
◙ Attempts to modify a readonly instance variable are caught
at compilation time rather than causing execution-time errors
◙ It’s always preferable to get bugs out at compile time, if
possible, rather than allowing them to slip through to execution
time (where studies have found that repairing bugs is often
much more costly)

85
◙ If a readonly instance variable is initialized to a constant
only in its declaration, it’s not necessary to have a separate
copy of the instance variable for every object of the class
◙ The variable should be declared const instead. Constants
declared with const are implicitly static, so there will only
be one copy for the entire class

86
C# 6 Get-Only Auto-Implemented Properties are readonly
◙ When an auto-implemented property has only a get accessor, the
property can be used only to read the value, so the compiler
implicitly declares the corresponding private instance variable
as readonly
◙ Get‐only auto‐implemented properties can be initialized in their
declarations or in constructors

87
◙ The Class View displays the fields, methods and properties for
all classes in a project
◙ Select View > Class View to display the Class View as a tab in
the same position within the IDE
◙ Figure-12 shows the Class View for the Time1 project of
Figure-1 (class Time1) and Figure-2 (class TimeTest1)

88
Figure-12: Class View of class Time1 (Figure-1) and class Time1Test (Figure-2) 89
◙ The view follows a hierarchical structure, with the project
name as the root
◙ When a class is selected, its members appear in the lower half
of the window
◙ public methods are indicated by purple boxes
◙ public properties are indicated by wrench icons
◙ If a class has any private members, those members’ icons
contain small padlocks

90
◙ You can use the Object Browser to learn about the
functionality provided by a specific class
◙ To open the Object Browser, select View > Object Browser
◙ Figure-13 depicts the Object Browser when the user navigates
to the Math class in namespace System in the assembly
mscorlib.dll (Microsoft Core Library)

91
Figure-13: Object Browser for class Math 92
◙ The Object Browser lists all methods provided by class Math
in the upper-right frame
◙ If you click the name of a member in the upper-right frame, a
description of that member appears in the lower-right frame
◙ The Object Browser can be a quick mechanism to learn about
a class or one of its methods

93
◙ Object initializers allow you to create an object and
initialize its public properties (and public instance
variables, if any) in the same statement
◙ This can be useful when a class does not provide an
appropriate constructor to meet your needs, but does provide
a constructor that can be called with no arguments and
properties that you can use to set the class’s data
◙ Each property name can appear only once in the object‐
initializer list
◙ The object initializer executes the property initializers
in the order in which they appear 94
◙ Following statements demonstrate object initializers using the
class Time2 from Figure-5
◙ new Time2 is immediately followed by an
object-initializer list—a comma-separated list in curly braces
({ }) of properties and their values
// create a Time2 object and initialize its properties
Var aTime= new Time2 {Hour = 14, Minute = 10, Second = 12};

// create a Time2 object and initialize its Minute property


Var bTime = new Time2 {Minute = 45};
95
◙ You can create operators that work with objects of your own
types—via a process called operator overloading
◙ You can overload most operators

96
◙ C#’s simple numeric types are value types
◙ C#’s simple types like int and double are actually aliases for
struct types—an int is defined by the struct
System.Int32, a long by System.Int64, a double by
System.Double and so on
◙ Operator overloading also can be applied to classes

97
When to Declare a struct Type
◙ Microsoft recommends using classes for most new types, but
recommends a struct if:
◘ the type represents a single value
◘ the size of an object is 16 bytes or smaller
◙ For the complete list of struct recommendations, see
https://msdn.microsoft.com/library/ms229017

98
◙ Value type ComplexNumber (Figure-14) overloads the plus (+),
minus (‐) and multiplication (*) operators to enable programs to
◘ add,
◘ subtract and
◘ Multiply
instances of class ComplexNumber using common mathematical
notation

99
Figure-14: Value Type that overloads operators for adding, subtracting and multiplying complex numbers (1 of 3) 100
Figure-14: Value Type that overloads operators for adding, subtracting and multiplying complex numbers (2 of 3) 101
Figure-14: Value Type that overloads operators for adding, subtracting and multiplying complex numbers (3 of 3) 102
◙ Unlike a class, you cannot define a parameterless
constructor for a struct
◙ The compiler always provides a default constructor that
initializes the struct’s instance variables to their default
values
◙ structs cannot specify initial values in instance variable or
property declarations

103
◙ Keyword operator, followed by an operator symbol (such as +),
indicates that a method overloads the specified operator
◙ Overloaded operator methods are required to be public and
static
◙ Methods that overload binary operators must take two
arguments—the first is the left operand and the second is the
right operand

104
◙ Overload operators to perform the same function or similar
functions on objects as the operators perform on objects of
simple types
◙ Avoid nonintuitive use of operators

105
◙ At least one parameter of an overloaded operator method must
be of the type in which the operator is overloaded
◙ This prevents you from changing how operators work on
simple types

106
Though you cannot overload the arithmetic assignment
operators (For example += and -=), C# allows you to use them with
any type that declares the corresponding arithmetic operator (For example
+ and -)

107
◙ Class ComplexTest (Figure15) demonstrates the overloaded
operators for adding, subtracting and multiplying
ComplexNumbers

108
Figure-15: Overloading operators for complex numbers (1 of 2) 109
Figure-15: Overloading operators for complex numbers (2 of 2) 110
◙ You can use extension methods to add functionality to an
existing type without modifying the type’s source code
◙ LINQ’s capabilities are implemented as extension methods
◙ Figure-16 uses extension methods to add two new methods to
class Time2 (Section 5)—DisplayTime and AddHours

111
Figure-16: Demonstration extension methods (1 of 4) 112
Figure-16: Demonstration extension methods (2 of 4) 113
Figure-16: Demonstration extension methods (3 of 4) 114
Figure-16: Demonstration extension methods (4 of 4) 115
◙ The this keyword before a method’s first parameter notifies
the compiler that the method extends an existing class
◙ The type of the first parameter specifies the type of object on
which you can call the extension method
◙ Extension methods must be defined as static methods in a
static class
◙ A static class can contain only static members and cannot
be instantiated

116
◙ When you call an extension method, you do not provide an
argument for the first parameter
◙ The compiler implicitly passes the object that calls the method
as the extension method’s first argument
◙ This allows you to call the extension method as if it were an
instance method
◙ IntelliSense displays extension methods with the class’s
instance methods and identifies them with a similar icon that
also has a down arrow

117
◙ Line 23 uses both extension methods (DisplayTime and
AddHours) in a single statement to add 15 hours to the original
myTime and display the result in the console
◙ Multiple method calls in the same statement are known as
cascaded method calls
◙ When a method returns an object, you can follow the method
call with a member access operator (.) then call a method on
the object that was returned
◙ The methods are called from left to right

118
◙ You can call an extension method via its fully qualified name by
using the name of the class in which the extension method is
defined (TimeExtensions), followed by the member access
operator (.), the method name (DisplayTime) and its argument
list
◙ When using the fully qualified method name, you must specify
an argument for extension method’s first parameter

119
◙ If a type for which you declare an extension method already
defines an instance method with the same name and a
compatible signature, the instance method will shadow (i.e.,
hide) the extension method
◙ If a predefined type is later updated to include an instance
method that shadows an extension method, the compiler does
not report any errors and the extension method does not
appear in IntelliSense

120

You might also like