1. Trang chủ
  2. » Ôn tập Sinh học

this site is individual site for ueh students of information management faculty this site provides some students resources of it courses such as computer network data structure and algorithm enterprise resource planning

67 6 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 67
Dung lượng 517,47 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Here, you will learn the role of implicit typing of local variables, partial methods, automatic properties, extension methods, anonymous types, and object initialization syntax.”... Road[r]

Trang 1

Chapter 14 C# 2008

Language Features

Trang 2

“With the release of NET 3.5, the C# language has been

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.”

Trang 3

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

Trang 4

14.1 Understanding Implicitly Typed Local Variables

 C# 2008 now provides a new keyword, var, which you can use in place of specifying a formal data type (such

as 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

static void DeclareImplicitVars() {

// Implicitly typed local variables // are declared as follows:

// var variableName = initialValue ; var myInt = 0 ;

var myBool = true ;

Trang 5

Implicitly 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

static void DeclareImplicitVars ()

{

// Implicitly typed local variables.

var myInt = 0 ;

var myBool = true ;

var myString = "Time, marches on ";

// Print out the underlying type.

Console WriteLine ("myInt is a: {0}", myInt GetType () Name );

Console WriteLine ("myBool is a: {0}", myBool GetType () Name );

Console WriteLine ("myString is a: {0}",

myString GetType () Name );

Trang 6

Implicitly Typed Local Variables

 You can use this implicit typing for any type including

arrays, generic types, and your own custom types

{

// More implicitly typed local variables.

var myMinivans = new List < MiniVan >();

Console WriteLine ("evenNumbers is a: {0}",

evenNumbers GetType () Name );

Trang 7

Use 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 8

Use of var Within foreach Constructs

 A foreach loop can make use of a strongly typed iterator when processing an implicitly defined local array

static void VarInForeachLoop ()

{

var evenNumbers = new int[] { 2 , 4 , 6 , 8 };

// Use a strongly typed System.Int32 to iterate over contents.

foreach (int item in evenNumbers )

{

Console WriteLine ("Item value: {0}", item );

}

Trang 9

Restrictions on Implicitly Typed Variables

 Implicit typing applies only to local variables in a method

or property scope

class ThisWillNeverCompile

{

// Error! var cannot be used as field data!

private var myInt = 10 ;

// Error! var cannot be used as a return value // or parameter type!

public var MyMethod ( var x , var y ){}

}

Trang 10

Restrictions 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

// Error! Must assign a value!

var myData ;

// Error! Must assign value at exact time of declaration!

var myInt ;

myInt = 0 ;

// Error! Can't assign null as initial value!

var myObj = null ;

Trang 11

Restrictions 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

// OK, is SportsCar is a reference type!

var myCar = new SportsCar ();

myCar = null ;

// Nope, can't define nullable implicit variables, // as implicit variables can never be initially assigned // null to begin with!

var ? nope = new SportsCar ();

Trang 12

Implicitly Typed Local Arrays

 Closely related to Implicitly Typed Local Variables

static void DeclareImplicitArrays()

Trang 13

Implicitly 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

// Error! Mixed types!

var d = new [ ] { 1 , "one", 2 , "two", false };

Trang 14

Implicit Typed Data Is Strongly Typed Data

 Implicit typing of local variables results in strongly typed data

 Type inference keeps the strongly typed aspect of the

C# language and affects only the declaration of variables

at compile time

static void ImplicitTypingIsStrongTyping () {

// The compiler knows "s" is a System.String.

var s = "This variable can only hold string data!";

s = "This is fine ";

Trang 15

Usefulness 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 16

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

Trang 17

14.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

public int PetName

{ get { return carName ; }

set { carName = value ; } } }

Trang 18

Automatic 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

class Car { // Automatic property syntax.

public string PetName { get ; set ; } }

Trang 19

public abstract string PetName { get ;

set ; } }

Trang 20

Automatic 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

// Read-only property? Error!

public int MyReadOnlyProp { get ; } // Write only property? Error!

public int MyWriteOnlyProp { set ; }

Trang 21

Interacting with Automatic Properties

 The class defining automatic properties will always need

to use property syntax to get and set the underlying

// No access to the private member in the defining // class Must use properties!

return string.Format( "PetName = {0}" , PetName);

} }

Trang 22

Interacting with Automatic Properties

 Assign and obtain the values using the expected

Trang 23

Restricting 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

// Anyone can get the PetName value, but

// only the defining type and the children can set it.

public int PetName

{

get { return carName ; }

protected set { carName = value ; }

}

Trang 24

Restricting 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

public string PetName { get ; protected set ; }

static void Main( string [ ] args)

{

// Error! Setting the PetName is only possible

// from within the Car type or by a child type!

c.PetName = "Frank" ;

Trang 25

Regarding 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 26

Regarding 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

static void Main (string[ ] args ) {

Garage g = new Garage ();

// OK, prints defualt value of zero.

Console WriteLine ("Number of Cars: {0}",

g NumberOfCars );

// Runtime error! Backing field is currently null!

Trang 27

Regarding 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

class Garage {

// The hidden backing field is set to zero!

public int NumberOfCars { get ; set ; }

// The hidden backing field is set to null!

public Car MyAuto { get ; set ; }

// Must use constructors to override default

// values assigned to hidden backing fields.

public Garage () {

MyAuto = new Car (); NumberOfCars = 1 ; }

public Garage ( Car car , int number ) {

MyAuto = car ; NumberOfCars = number ; }

Trang 28

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

Trang 29

14.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 30

Defining 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

Trang 31

static class MyExtensions {

// This method allows any object to display the assembly it is defined in.

public static void DisplayDefiningAssembly( this object obj)

{

Console.WriteLine( "{0} lives here:\n\t->{1}\n" , obj.GetType().Name,

Assembly.GetAssembly(obj.GetType()));

}

// This method allows any integer to reverse its digits.

// For example, 56 would return 65.

public static int ReverseDigits( this int i)

{

// Translate int into a string, and then get all the characters.

char [ ] digits = i.ToString().ToCharArray();

// Now reverse items in the array.

Array.Reverse(digits);

// Put back into string.

string newDigits = new string (digits);

// return the modified string back as an int.return int.Parse(newDigits);

}

}

Example 14.1 Defining Extension Method

Trang 32

Defining 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

Trang 33

Invoking 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 34

static void Main( string [ ] args)

{

// The int has assumed a new identity!

int myInt = 12345678;

myInt.DisplayDefiningAssembly();

// So has the DataSet!

System.Data.DataSet d = new System.Data.DataSet();

d.DisplayDefiningAssembly();

// And the SoundPlayer!

System.Media.SoundPlayer sp = new System.Media.SoundPlayer();

sp.DisplayDefiningAssembly();

// Use new integer functionality.

Console.WriteLine( "Value of myInt: {0}" , myInt);

Console.WriteLine( "Reversed digits of myInt: {0}" , myInt.ReverseDigits());

Trang 35

Invoking 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 36

private static void Main (string[ ] args )

{

int myInt = 12345678 ;

MyExtensions DisplayDefiningAssembly ( myInt );

DataSet d = new DataSet ();

MyExtensions DisplayDefiningAssembly ( d );

SoundPlayer sp = new SoundPlayer ();

MyExtensions DisplayDefiningAssembly ( sp );

Console WriteLine ( "Value of myInt: {0}" , myInt );

Console WriteLine ( "Reversed digits of myInt: {0}" ,

MyExtensions ReverseDigits ( myInt ));

TesterUtilClass Foo ( myInt );

TesterUtilClass Foo ( myInt , "Ints that Foo? Who would have thought

Trang 37

The 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

public class Car

{ public int Speed ; public int SpeedUp () {

return ++ Speed ; }

}

Trang 38

The 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

public static class CarExtensions

{ public static int SlowDown ( this Car c ) {

// Error! This method is not deriving from Car!

return Speed ;

Trang 39

The 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 public static class CarExtensions

{ public static int SlowDown ( this Car

c ) { // OK!

return c Speed ; }

Trang 40

The Scope of an Extension Method

 At this point, you could create a Car object and invoke the SpeedUp() and SlowDown() methods as follows

static void UseCar () {

Car c = new Car ();

Console WriteLine ("Speed: {0}",

c SpeedUp ());

Console WriteLine ("Speed: {0}",

c SlowDown ());

}

Ngày đăng: 25/01/2021, 15:15

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w