Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C-sharp language specification.2004.pdf
Скачиваний:
12
Добавлен:
23.08.2013
Размер:
2.55 Mб
Скачать

 

C# LANGUAGE SPECIFICATION

1

[DllImport("kernel32", SetLastError=true)]

2

static extern int GetCurrentDirectory(int bufSize, StringBuilder buf);

3

[DllImport("kernel32", SetLastError=true)]

4static extern bool SetCurrentDirectory(string name);

5}

6end example]

717.5.8 Method body

8The method-body of a method declaration consists of either a block or a semicolon.

9Abstract and external method declarations do not provide a method implementation, so their method bodies

10simply consist of a semicolon. For any other method, the method body is a block (§15.2) that contains the

11statements to execute when that method is invoked.

12When the return type of a method is void, return statements (§15.9.4) in that method’s body are not

13permitted to specify an expression. If execution of the method body of a void method completes normally

14(that is, control flows off the end of the method body), that method simply returns to its caller.

15When the return type of a method is not void, each return statement in that method body shall specify an

16expression of a type that is implicitly convertible to the return type. The endpoint of the method body of a

17value-returning method shall not be reachable. In other words, in a value-returning method, control is not

18permitted to flow off the end of the method body.

19[Example: In the following code

20class A

21{

22

public int F() {}

// Error, return value required

23

public int G() {

 

24

return 1;

 

25

}

 

26

public int H(bool b) {

 

27

if (b) {

 

28

return 1;

 

29

}

 

30

else {

 

31

return 0;

 

32

}

 

33}

34}

35the value-returning F method results in a compile-time error because control can flow off the end of the

36method body. The G and H methods are correct because all possible execution paths end in a return

37statement that specifies a return value. end example]

3817.5.9 Method overloading

39The method overload resolution rules are described in §14.4.2.

4017.6 Properties

41A property is a member that provides access to a characteristic of an object or a class. Examples of

42properties include the length of a string, the size of a font, the caption of a window, the name of a customer,

43and so on. Properties are a natural extension of fields—both are named members with associated types, and

44the syntax for accessing fields and properties is the same. However, unlike fields, properties do not denote

45storage locations. Instead, properties have accessors that specify the statements to be executed when their

46values are read or written. Properties thus provide a mechanism for associating actions with the reading and

47writing of an object’s characteristics; furthermore, they permit such characteristics to be computed.

48Properties are declared using property-declarations:

290

 

Chapter 17 Classes

1

property-declaration:

2

attributesopt property-modifiersopt type member-name { accessor-declarations }

3

property-modifiers:

4

property-modifier

5

property-modifiers property-modifier

6

property-modifier:

7

new

8

public

9

protected

10

internal

11

private

12

static

13

virtual

14

sealed

15

override

16

abstract

17extern

18member-name:

19

identifier

20

interface-type . identifier

21A property-declaration can include a set of attributes (§24) and a valid combination of the four access

22modifiers (§17.2.3), the new (§17.2.2), static (§17.6.1), virtual (§17.5.3, §17.6.3), override (§17.5.4,

23§17.6.3), sealed (§17.5.5), abstract (§17.5.6, §17.6.3), and extern modifiers.

24Property declarations are subject to the same rules as method declarations (§17.5) with regard to valid

25combinations of modifiers.

26The type of a property declaration specifies the type of the property introduced by the declaration, and the

27member-name specifies the name of the property. Unless the property is an explicit interface member

28implementation, the member-name is simply an identifier. For an explicit interface member implementation

29(§20.4.1), the member-name consists of an interface-type followed by a “.” and an identifier.

30The type of a property shall be at least as accessible as the property itself (§10.5.4).

31The accessor-declarations, which shall be enclosed in “{” and “}” tokens, declare the accessors (§17.6.2) of

32the property. The accessors specify the executable statements associated with reading and writing the

33property.

34Even though the syntax for accessing a property is the same as that for a field, a property is not classified as

35a variable. Thus, it is not possible to pass a property as a ref or out argument.

36When a property declaration includes an extern modifier, the property is said to be an external property.

37Because an external property declaration provides no actual implementation, each of its accessor-

38declarations consists of a semicolon.

3917.6.1 Static and instance properties

40When a property declaration includes a static modifier, the property is said to be a static property. When

41no static modifier is present, the property is said to be an instance property.

42A static property is not associated with a specific instance, and it is a compile-time error to refer to this in

43the accessors of a static property.

44An instance property is associated with a given instance of a class, and that instance can be accessed as

45this (§14.5.7) in the accessors of that property.

46The differences between static and instance members are discussed further in §17.2.5.

291

C# LANGUAGE SPECIFICATION

117.6.2 Accessors

2The accessor-declarations of a property specify the executable statements associated with reading and

3writing that property.

4accessor-declarations:

5

get-accessor-declaration set-accessor-declarationopt

6

set-accessor-declaration get-accessor-declarationopt

7

get-accessor-declaration:

 

 

8

attributesopt accessor-modifieropt

get

accessor-body

9

set-accessor-declaration:

 

 

10

attributesopt accessor-modifieropt

set

accessor-body

11

accessor-modifier:

 

 

12

protected

 

 

13

internal

 

 

14

private

 

 

15

protected internal

 

 

16internal protected

17accessor-body:

18

block

19;

20The accessor declarations consist of a get-accessor-declaration, a set-accessor-declaration, or both. Each

21accessor declaration consists of the token get or set followed by an accessor-body. For abstract and

22extern properties, the accessor-body for each accessor specified is simply a semicolon. For the accessors

23of any non-abstract, non-extern property, the accessor-body is a block which specifies the statements to be

24executed when the corresponding accessor is invoked.

25A get accessor corresponds to a parameterless method with a return value of the property type. Except as

26the target of an assignment, when a property is referenced in an expression, the get accessor of the property

27is invoked to compute the value of the property (§14.1.1). The body of a get accessor shall conform to the

28rules for value-returning methods described in §17.5.8. In particular, all return statements in the body of a

29get accessor shall specify an expression that is implicitly convertible to the property type. Furthermore, the

30endpoint of a get accessor shall not be reachable.

31A set accessor corresponds to a method with a single value parameter of the property type and a void

32return type. The implicit parameter of a set accessor is always named value. When a property is

33referenced as the target of an assignment (§14.13), or as the operand of ++ or –- (§14.5.9, 14.6.5), the set

34accessor is invoked with an argument that provides the new value (§14.13.1). The body of a set accessor

35shall conform to the rules for void methods described in §17.5.8. In particular, return statements in the

36set accessor body are not permitted to specify an expression. Since a set accessor implicitly has a

37parameter named value, it is a compile-time error for a local variable declaration or a local constant

38declaration in a set accessor to have that name.

39Based on the presence or absence of the get and set accessors, a property is classified as follows:

40A property that includes both a get accessor and a set accessor is said to be a read-write property.

41A property that has only a get accessor is said to be a read-only property. It is a compile-time error for

42a read-only property to be the target of an assignment.

43A property that has only a set accessor is said to be a write-only property. Except as the target of a

44simple assignment, it is a compile-time error to reference a write-only property in an expression. [Note:

45The preand postfix ++ and -- operators and compound assignment operators cannot be applied to

46write-only properties, since these operators read the old value of their operand before they write the new

47one. end note]

48The use of accessor-modifiers is governed by the following restrictions:

292

Chapter 17 Classes

1An accessor-modifier cannot be used in an interface or in an explicit interface member implementation.

2For a property or indexer that has no override modifer, an accessor-modifier is permitted only if the

3property or indexer has both a get and set accessor, and then is permitted only on one of those

4accessors.

5For a property or indexer that includes an override modifer, the accessor-modifier of an accessor shall

6match the accessor-modifier, if any, of the accessor being overridden.

7The accessor-modifier shall declare an accessibility that is strictly more restrictive than the declared

8accessibility of the property or indexer itself. To be precise:

9o If the property or indexer has a declared accessibility of public, any accessor-modifier can be used.

10o If the property or indexer has a declared accessibility of protected internal, the accessor-modifier can

11be internal, protected, or private.

12o If the property or indexer has a declared accessibility of internal or protected, the accessor-modifier

13shall be private.

14o If the property or indexer has a declared accessibility of private, no accessor-modifier shall be used.

15If an accessor has an accessor-modifier, the accessibility domain (§10.5.2) of the accessor is determined

16using the declared accessibility of the accessor-modifier. If an accessor does not have an accessor-modifier,

17the accessibility domain of the accessor is determined from the declared accessibility of the property or

18indexer.

19[Example: In the following code

20public class Button: Control

21{

22

private string caption;

23

public string Caption {

24

get {

25

return caption;

26

}

27

set {

28

if (caption != value) {

29

caption = value;

30

Repaint();

31

}

32

}

33

}

34

public override void Paint(Graphics g, Rectangle r) {

35

// Painting code goes here

36}

37}

38the Button control declares a public Caption property. The get accessor of the Caption property returns

39the string stored in the private caption field. The set accessor checks if the new value is different from the

40current value, and if so, it stores the new value and repaints the control. Properties often follow the pattern

41shown above: The get accessor simply returns a value stored in a private field, and the set accessor

42modifies that private field and then performs any additional actions required to fully update the state of the

43object.

44Given the Button class above, the following is an example of use of the Caption property:

45Button okButton = new Button();

46

okButton.Caption = "OK";

//

Invokes

set

accessor

47

string s = okButton.Caption;

//

Invokes

get

accessor

48Here, the set accessor is invoked by assigning a value to the property, and the get accessor is invoked by

49referencing the property in an expression. end example]

50The get and set accessors of a property are not distinct members, and it is not possible to declare the

51accessors of a property separately. [Example: The example

293

C# LANGUAGE SPECIFICATION

1class A

2{

3

private string name;

 

4

public string Name {

// Error, duplicate member name

5

get { return name; }

 

6

}

 

7

public string Name {

// Error, duplicate member name

8

set { name = value; }

 

9}

10}

11does not declare a single read-write property. Rather, it declares two properties with the same name, one

12read-only and one write-only. Since two members declared in the same class cannot have the same name, the

13example causes a compile-time error to occur. end example]

14When a derived class declares a property by the same name as an inherited property, the derived property

15hides the inherited property with respect to both reading and writing. [Example: In the following code

16class A

17{

18

public

int P {

19

set

{…}

20}

21}

22class B: A

23{

24

new public int P {

25

get {…}

26}

27}

28the P property in B hides the P property in A with respect to both reading and writing. Thus, in the

29statements

30B b = new B();

31b.P = 1; // Error, B.P is read-only

32((A)b).P = 1; // Ok, reference to A.P

33the assignment to b.P causes a compile-time error to be reported, since the read-only P property in B hides

34the write-only P property in A. Note, however, that a cast can be used to access the hidden P property. end

35example]

36Unlike public fields, properties provide a separation between an object’s internal state and its public

37interface. [Example: Consider the example:

38class Label

39{

40

private int x, y;

41

private string caption;

42

public Label(int x, int y, string caption) {

43

this.x = x;

44

this.y = y;

45

this.caption = caption;

46

}

47

public int X {

48

get { return x; }

49

}

50

public int Y {

51

get { return y; }

52

}

53

public Point Location {

54

get { return new Point(x, y); }

55

}

294

 

Chapter 17 Classes

1

public string Caption {

2

get { return caption; }

3}

4}

5Here, the Label class uses two int fields, x and y, to store its location. The location is publicly exposed

6both as an X and a Y property and as a Location property of type Point. If, in a future version of Label,

7it becomes more convenient to store the location as a Point internally, the change can be made without

8affecting the public interface of the class:

9class Label

10{

11

private Point location;

12

private string caption;

13

public Label(int x, int y, string caption) {

14

this.location = new Point(x, y);

15

this.caption = caption;

16

}

17

public int X {

18

get { return location.x; }

19

}

20

public int Y {

21

get { return location.y; }

22

}

23

public Point Location {

24

get { return location; }

25

}

26

public string Caption {

27

get { return caption; }

28}

29}

30Had x and y instead been public readonly fields, it would have been impossible to make such a change

31to the Label class. end example]

32[Note: Exposing state through properties is not necessarily any less efficient than exposing fields directly. In

33particular, when a property is non-virtual and contains only a small amount of code, the execution

34environment might replace calls to accessors with the actual code of the accessors. This process is known as

35inlining, and it makes property access as efficient as field access, yet preserves the increased flexibility of

36properties. end note]

37[Example: Since invoking a get accessor is conceptually equivalent to reading the value of a field, it is

38considered bad programming style for get accessors to have observable side-effects. In the example

39class Counter

40{

41

private int next;

42

public int Next {

43

get { return next++; }

44}

45}

46the value of the Next property depends on the number of times the property has previously been accessed.

47Thus, accessing the property produces an observable side effect, and the property should be implemented as

48a method instead. end example]

49[Note: The “no side-effects” convention for get accessors doesn’t mean that get accessors should always

50be written to simply return values stored in fields. Indeed, get accessors often compute the value of a

51property by accessing multiple fields or invoking methods. However, a properly designed get accessor

52performs no actions that cause observable changes in the state of the object. end note]

53Properties can be used to delay initialization of a resource until the moment it is first referenced. [Example:

54using System.IO;

295

C# LANGUAGE SPECIFICATION

1public class Console

2{

3

private static TextReader reader;

4

private static TextWriter writer;

5

private static TextWriter error;

6

public static TextReader In {

7

get {

8

if (reader == null) {

9

reader = new StreamReader(Console.OpenStandardInput());

10

}

11

return reader;

12

}

13

}

14

public static TextWriter Out {

15

get {

16

if (writer == null) {

17

writer = new StreamWriter(Console.OpenStandardOutput());

18

}

19

return writer;

20

}

21

}

22

public static TextWriter Error {

23

get {

24

if (error == null) {

25

error = new StreamWriter(Console.OpenStandardError());

26

}

27

return error;

28

}

29

}

30

31}

32The Console class contains three properties, In, Out, and Error, that represent the standard input, output,

33and error devices, respectively. By exposing these members as properties, the Console class can delay their

34initialization until they are actually used. For example, upon first referencing the Out property, as in

35Console.Out.WriteLine("hello, world");

36the underlying TextWriter for the output device is created. But if the application makes no reference to the

37In and Error properties, then no objects are created for those devices. end example]

38The presence of an accessor-modifier never affects member lookup (§14.3) or overload resolution (§14.4.2).

39The modifiers on the property or indexer always determine which property or indexer is bound to, regardless

40of the context of the access.

41Once a particular property or indexer has been selected, the accessibility domains of the specific accessors

42involved are used to determine if that usage is valid:

43If the usage is as a value (§14.1.1), the get accessor shall exist and be accessible.

44If the usage is as the target of a simple assignment (§14.13.1), the set accessor shall exist and be

45accessible.

46If the usage is as the target of compound assignment (§14.13.2), or as the target of the ++ or --

47operators (§14.5.9, §14.6.5), both the get accessors and the set accessor shall exist and be accessible.

48[Example: In the following example, the property A.Text is hidden by the property B.Text, even in

49contexts where only the set accessor is called. In contrast, the property B.Count is not accessible to class

50M, so the accessible property A.Count is used instead.

51class A

52{

53

public string Text {

54

get { return "hello"; }

55

set { }

56

}

296

Соседние файлы в предмете Электротехника