Here, you will learn the role of implicit typing of local variables, partial methods, automatic properties, extension methods, anonymous types, and object initialization syntax.” 2... 14
Trang 2Objectives
“With the release of NET 3.5, the C# language has been enhanced to support a great number of new programming constructs, many of which are used to enable the LINQ API (which you will begin to examine in Chapter 15) Here, you will learn the role of implicit typing of local variables, partial methods, automatic properties, extension methods, anonymous types, and object initialization syntax.”
2
Trang 314.1 Understanding Implicitly Typed Local Variables
14.2 Understanding Automatic Properties
14.3 Understanding Extension Methods
14.4 Understanding Partial Methods
14.5 Understanding Object Initializer Syntax
14.6 Understanding Anonymous Types
Trang 4as int, bool, or string) The compiler will automatically
infer the underlying data type based on the initial value used to initialize the local data point
Trang 5Implicitly Typed Local Variables
In this case, the compiler is able to infer that myInt is in fact a System.Int32, myBool is a System.Boolean, and myString is indeed of type System.String, given the
initially assigned value
Trang 6Implicitly Typed Local Variables
You can use this implicit typing for any type including
arrays, generic types, and your own custom types
6
Trang 7Use of var Within foreach Constructs
Use of implicit typing within a foreach looping construct
static void VarInForeachLoop()
{
var evenNumbers = new int[] { 2, 4, 6, 8 };
// Use "var" in a standard foreach loop.
foreach (var item in evenNumbers)
{
Console.WriteLine( "Item value: {0}" , item);
}
}
Trang 8Use of var Within foreach Constructs
A foreach loop can make use of a strongly typed iterator when processing an implicitly defined local array
8
Trang 9Restrictions on Implicitly Typed Variables
Implicit typing applies only to local variables in a method
or property scope
Trang 10Restrictions on Implicitly Typed Variables
Local variables declared with the var keyword must be assigned an initial value at the exact time of declaration and cannot be assigned the initial value of null
10
Trang 11Restrictions on Implicitly Typed Variables
It is permissible to return an implicitly typed local variable
to the caller, provided that the method return type is the same underlying type as the var-defined data point
Cannot define a nullable implicitly typed local variable
using the C# ? token
Trang 12Implicitly Typed Local Arrays
Closely related to Implicitly Typed Local Variables
Trang 13Implicitly Typed Local Arrays
The items in the array’s initialization list must be of the same underlying type (all ints, all strings, etc.)
An implicitly typed local array does not default to
System.Object
Trang 14 Type inference keeps the strongly typed aspect of the
C# language and affects only the declaration of variables
at compile time
14
Trang 15Usefulness of Implicitly Typed Local
Variables
Using var to declare local variables simply for the sake of doing so really brings little to the table
Doing so can be confusing to others reading your code
As it becomes harder to quickly determine the underlying data type
Therefore, if you know you need an int, declare an int!
Trang 16Roadmap
14.1 Understanding Implicitly Typed Local Variables
14.2 Understanding Automatic Properties
14.3 Understanding Extension Methods
14.4 Understanding Partial Methods
14.5 Understanding Object Initializer Syntax
14.6 Understanding Anonymous Types
16
Trang 1714.2 Understanding Automatic Properties
NET programming languages prefer the use of type
properties to safely obtain and assign private data fields
of a type, rather than using traditional GetXXX() and
SetXXX() methods
Trang 18Automatic Properties
C# 2008 now provides automatic property syntax
This feature will offload the work of defining a private backing field and the related C# property member to the compiler using a new bit of syntax
Under C# 2008, the previous Car type could now be
defined as
18
Trang 19Automatic properties
If you did intend to define an abstract property in the Car type, you would need to make use of the C# abstract
keyword as
Trang 20Automatic properties
When defining automatic properties, you simply specify the access modifier, underlying data type, property
name, and empty get/set scopes
it is not possible to build read-only or write-only
automatic properties
20
Trang 21Interacting with Automatic Properties
The class defining automatic properties will always need
to use property syntax to get and set the underlying
public string PetName { get; set; }
public override string ToString()
Trang 22Interacting with Automatic Properties
Assign and obtain the values using the expected
property syntax
22
Trang 23Restricting Access on Automatic Properties
NET property can be constructed in such a way that the get and set logic is assigned a unique access modifier
For example, it is possible to define a public get scope and a more restrictive protected scope as
Trang 24Restricting Access on Automatic Properties
This same possibility is allowed using automatic property syntax as
With this update, the previous Main() method would now generate a compiler error when attempting to assign the value of the PetName property
24
Trang 25Regarding Automatic Properties and
Default Values
If use automatic property syntax to wrap a reference
type, the hidden private reference type will also be set to
a default value of null
class Garage {
// The hidden int backing field is set to zero!
public int NumberOfCars { get; set; } // The hidden Car backing field is set to null!
public Car MyAuto { get; set; } }
Trang 26Regarding Automatic Properties and Default Values
Given C#’s default values for field data, you would be
able to print out the value of NumberOfCars as is, but if you directly invoke MyAuto, you will receive a null
reference exception
26
Trang 27Regarding Automatic Properties and Default Values
Given that the private backing fields are created at
compile time, you will be unable to make use of C# field initialization syntax to allocate the reference type directly with the new keyword
Trang 28Roadmap
14.1 Understanding Implicitly Typed Local Variables
14.2 Understanding Automatic Properties
14.3 Understanding Extension Methods
14.4 Understanding Partial Methods
14.5 Understanding Object Initializer Syntax
14.6 Understanding Anonymous Types
28
Trang 2914.3 Understanding Extension Methods
Allow existing compiled types as well as types currently being compiled to gain new functionality without needing
to directly update the type being extended
Add functionality to precompiled types while providing the illusion these methods were there all along
With C# 2008, you can
define extension method
invoke extension methods on an instance level
invoke extension methods statically
Trang 30Defining Extension Methods
Create a new Console Application named
ExtensionMethods Now, assume you are authoring a utility class named MyExtensions that defines two
extension methods
The first method allows any object in the NET base
class libraries to have a brand-new method named
DisplayDefiningAssembly() that makes use of types in the System.Reflection namespace to display the
assembly of the specified type
The second extension method, named ReverseDigits(), allows any System.Int32 to obtain a new version of itself where the value is reversed digit by digit
30
Trang 31Example 14.1 Defining Extension Method
Trang 32Defining Extension Methods
Given that DisplayDefiningAssembly() has been
prototyped to extend System.Object, any type in any
assembly now has this new member
However, ReverseDigits() has been prototyped to only extend integer types, and therefore if anything other than
an integer attempts to invoke this method, you will
receive a compile-time error
A given extension method could have multiple parameters, but only the first parameter can be qualified with this
32
Trang 33Invoking Extension Methods on an Instance Level
All objects have a new method named
DisplayDefiningAssembly(), while System.Int32 types
(and only integers) have methods named
ReverseDigits() and Foo()
Trang 34Example 14.2 Invoking Extension Methods on an Instance Level
Trang 35Invoking Extension Methods Statically
Recall that the first parameter of an extension method is marked with the this keyword, followed by the type of
item the method is applicable to
If we peek at what is happening behind the scenes (as verified
by a tool such as ildasm.exe), we will find that the compiler simply calls the “normal” static method, passing in the variable calling the method as a parameter (e.g., it is the value of this)
Trang 36Example 14.3 Invoking Extension Methods Statically
Trang 37The Scope of an Extension Method
Extension methods do not have direct access to the
members of the type they are extending
Consider the following simple Car type
Trang 38The Scope of an Extension Method
If you were to build an extension method for the Car type named SlowDown(), you do not have direct access to
the members of Car within the scope of the extension
method as we are not performing an act of classical
inheritance
38
Trang 39The Scope of an Extension Method
The problem here is that the static SlowDown()
extension method is attempting to access the Speed
field of the Car type
Because SlowDown() is a static member of the CarExtensions class, Speed does not exist in this context!
Permissible to make use of the thisqualified parameter to access all public members (and only the public members) of the type being extending
Trang 40The Scope of an Extension Method
At this point, you could create a Car object and invoke the SpeedUp() and SlowDown() methods as follows
40
Trang 41Importing Types That Define Extension
Methods
When partition a set of
static classes containing
extension methods in a
unique namespace, other
namespaces in that
assembly will make use of
the standard C# using
keyword to import not only
the static classes
themselves, but also each
of the supported extension
methods
Trang 4242
Trang 43The IntelliSense of Extension Methods
It is certainly possible to become confused when
examining an existing code base
For example, assume you have imported a namespace that defined some number of extension methods
authored by a teammate As you are authoring your
code, you might create a variable of the extended type, apply the dot operator, and find dozens of new methods that are not members of the original class definition!
Any method marked with this visual icon is a friendly
reminder that the method is defined outside of the
original class definition via an extension method
Trang 44Building and Using Extension Libraries
Compile your library and reference the
MyExtensionsLibrary.dll assembly within new NET projects
Microsoft recommends placing types that have extension
methods in a dedicated assembly (within a dedicated
namespace)
44
Trang 45Building and Using Extension Libraries
At this point, you can compile your library and reference the MyExtensionsLibrary.dll assembly within new NET projects
The new functionality provided to System.Object and
System.Int32 can be used by any application that references the library
To test this out
Add a new Console Application project (named
Trang 46Example 14.4 Building and Using Extension Libraries
Trang 4714.1 Understanding Implicitly Typed Local Variables
14.2 Understanding Automatic Properties
14.3 Understanding Extension Methods
14.4 Understanding Partial Methods
14.5 Understanding Object Initializer Syntax
14.6 Understanding Anonymous Types
Trang 4814.4 Understanding Partial Methods
C# 2008 widens the scope of the partial keyword in that
it can now be applied on the method level
Important restrictions:
Partial methods can only be defined within a partial class
Partial methods must return void
Partial methods can be static or instance level
Partial methods can have arguments (including parameters
modified by this, ref, or params—but not with the out modifier)
Partial methods are always implicitly private.
48
Trang 49A First Look
To see the implications of defining a partial method, create a new Console Application project named PartialMethods Now, define a new class named CarLocator within a C# file named CarLocator.cs
Trang 5050
Trang 51A First Look
The reason for this strange stripping away of code has to
do with the fact that our partial VerifyDuplicates() method was never given a true implementation
Trang 52A First Look
We would now find that the full scope of the CarLocator class is taken into account at compile time (as shown in the following approximate C# code)
52
Trang 53Uses of Partial Methods
In C# 2008, partial methods will more likely than not be the least used among them
In the current example, the VerifyDuplicates() method was marked
as partial for illustrative purposes; however, imagine that this method, if implemented, had to perform some very intensive calculations
By marking this method with the partial modifier, other class builders have the option of providing implementation details if they so choose
In this case, partial methods provide a cleaner solution than using preprocessor directives, supplying “dummy” implementations to virtual methods or throwing NotImplementedException objects
The most common use of this syntax is to define what are termed lightweight events
Trang 54Roadmap
14.1 Understanding Implicitly Typed Local Variables
14.2 Understanding Automatic Properties
14.3 Understanding Extension Methods
14.4 Understanding Partial Methods
14.5 Understanding Object Initializer Syntax
14.6 Understanding Anonymous Types
54
Trang 5514.5 Understanding Object Initializer Syntax
A new way to hydrate the state of a new class or
// Make a Point by setting each property manually
Point firstPoint = new Point();
firstPoint.X = 10;
firstPoint.Y = 10;
// or make a Point via a custom constructor
Point anotherPoint = new Point(20, 20);
// or make some Point types using the new object init syntax var yetAnotherPoint = new Point { X = 30, Y = 30 };
Point finalPoint = new Point { X = 30, Y = 30 };
}
Trang 56Calling Custom Constructors with
Initialization Syntax
The previous examples initialized Point types by
implicitly calling the default constructor on the type
If you wish to be very clear about this, it is permissible to explicitly call the default constructor as follows
56
Trang 57Calling Custom Constructors with
Initialization Syntax
Therefore, the following Point declaration results in an X value of 100 and a Y value of 100, regardless of the fact that our constructor arguments specified the values 10 and 16
Given the current definition of our Point type, calling the custom constructor while using initialization syntax is not terribly useful (and more than a bit verbose)
Trang 58Example 14.5 Calling Custom Constructors with Initialization Syntax
Trang 5914.1 Understanding Implicitly Typed Local Variables
14.2 Understanding Automatic Properties
14.3 Understanding Extension Methods
14.4 Understanding Partial Methods
14.5 Understanding Object Initializer Syntax
14.6 Understanding Anonymous Types
Trang 60 As of C# 2008, we are now provided with a massive
shortcut for this very situation termed anonymous types, which in many ways is a natural extension of C#’s
anonymous methods syntax
60