分享
 
 
 

17.6.2 Accessors

王朝other·作者佚名  2006-05-09
窄屏简体版  字體: |||超大  

The accessor-declarations of a property specify the

executable statements associated with reading and

writing that property.

accessor-declarations:

get-accessor-declaration set-accessor-declarationopt

set-accessor-declaration get-accessor-declarationopt

get-accessor-declaration:

attributesopt get accessor-body

set-accessor-declaration:

attributesopt set accessor-body

accessor-body:

block

;

The accessor declarations consist of a get-accessor-declaration, a

set-accessor-declaration, or both. Each

accessor declaration consists of the token get or set followed by an

accessor-body. For abstract and extern

properties, the accessor-body for each accessor specified is simply a

semicolon. For the accessors of any nonabstract,

non-extern property, the accessor-body is a block which specifies the

statements to be executed when

the corresponding accessor is invoked.

A get accessor corresponds to a parameterless method with a return value of

the property type. Except as the

target of an assignment, when a property is referenced in an expression,

the get accessor of the property is

invoked to compute the value of the property (§14.1.1). The body of a get

accessor must conform to the rules for

value-returning methods described in §17.5.8. In particular, all return

statements in the body of a get accessor

must specify an expression that is implicitly convertible to the property

type. Furthermore, the endpoint of a get

accessor must not be reachable.

A set accessor corresponds to a method with a single value parameter of the

property type and a void return

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

a property is referenced as the

target of an assignment (§14.13), or as the operand of ++ or .- (§14.5.9,

14.6.5), the set accessor is invoked

with an argument (whose value is that of the right-hand side of the

assignment or the operand of the ++ or .-

operator) that provides the new value (§14.13.1). The body of a set

accessor must conform to the rules for void

methods described in §17.5.8. In particular, return statements in the set

accessor body are not permitted to

specify an expression. Since a set accessor implicitly has a parameter

named value, it is a compile-time error

for a local variable declaration or a local constant declaration in a set

accessor to have that name.

Based on the presence or absence of the get and set accessors, a property

is classified as follows:

. A property that includes both a get accessor and a set accessor is said

to be a read-write property.

. A property that has only a get accessor is said to be a read-only

property. It is a compile-time error for a

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

. A property that has only a set accessor is said to be a write-only

property. Except as the target of an

assignment, it is a compile-time error to reference a write-only property

in an expression. [Note: The pre- and

postfix ++ and -- operators cannot be applied to write-only properties,

since these operators read the old

value of their operand before they write the new one. end note]

[Example: In the example

public class Button: Control

{

private string caption;

C# LANGUAGE SPECIFICATION

242

public string Caption {

get {

return caption;

}

set {

if (caption != value) {

caption = value;

Repaint();

}

}

}

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

// Painting code goes here

}

}

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

the Caption property returns the

string stored in the private caption field. The set accessor checks if the

new value is different from the current

value, and if so, it stores the new value and repaints the control.

Properties often follow the pattern shown above:

The get accessor simply returns a value stored in a private field, and the

set accessor modifies that private field

and then performs any additional actions required to fully update the state

of the object.

Given the Button class above, the following is an example of use of the

Caption property:

Button okButton = new Button();

okButton.Caption = "OK"; // Invokes set accessor

string s = okButton.Caption; // Invokes get accessor

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

the get accessor is invoked by

referencing the property in an expression. end example]

The get and set accessors of a property are not distinct members, and it is

not possible to declare the accessors

of a property separately. [Note: As such, it is not possible for the two

accessors of a read-write property to have

different accessibility. end note] [Example: The example

class A

{

private string name;

public string Name { // Error, duplicate member name

get { return name; }

}

public string Name { // Error, duplicate member name

set { name = value; }

}

}

does not declare a single read-write property. Rather, it declares two

properties with the same name, one readonly

and one write-only. Since two members declared in the same class cannot

have the same name, the example

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

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

property, the derived property hides

the inherited property with respect to both reading and writing. [Example:

In the example

class A

{

public int P {

set {.}

}

}

class B: A

{

new public int P {

get {.}

}

}

Chapter 17 Classes

243

the P property in B hides the P property in A with respect to both reading

and writing. Thus, in the statements

B b = new B();

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

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

the assignment to b.P causes a compile-time error to be reported, since the

read-only P property in B hides the

write-only P property in A. Note, however, that a cast can be used to

access the hidden P property. end example]

Unlike public fields, properties provide a separation between an object.s

internal state and its public interface.

[Example: Consider the example:

class Label

{

private int x, y;

private string caption;

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

this.x = x;

this.y = y;

this.caption = caption;

}

public int X {

get { return x; }

}

public int Y {

get { return y; }

}

public Point Location {

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

}

public string Caption {

get { return caption; }

}

}

Here, the Label class uses two int fields, x and y, to store its location.

The location is publicly exposed both as

an X and a Y property and as a Location property of type Point. If, in a

future version of Label, it becomes

more convenient to store the location as a Point internally, the change can

be made without affecting the public

interface of the class:

class Label

{

private Point location;

private string caption;

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

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

this.caption = caption;

}

public int X {

get { return location.x; }

}

public int Y {

get { return location.y; }

}

public Point Location {

get { return location; }

}

public string Caption {

get { return caption; }

}

}

C# LANGUAGE SPECIFICATION

244

Had x and y instead been public readonly fields, it would have been

impossible to make such a change to the

Label class. end example]

[Note: Exposing state through properties is not necessarily any less

efficient than exposing fields directly. In

particular, when a property is non-virtual and contains only a small amount

of code, the execution environment

may replace calls to accessors with the actual code of the accessors. This

process is known as inlining, and it

makes property access as efficient as field access, yet preserves the

increased flexibility of properties. end note]

[Example: Since invoking a get accessor is conceptually equivalent to

reading the value of a field, it is

considered bad programming style for get accessors to have observable

side-effects. In the example

class Counter

{

private int next;

public int Next {

get { return next++; }

}

}

the value of the Next property depends on the number of times the property

has previously been accessed. Thus,

accessing the property produces an observable side effect, and the property

should be implemented as a method

instead. end example]

[Note: The .no side-effects. convention for get accessors doesn.t mean that

get accessors should always be

written to simply return values stored in fields. Indeed, get accessors

often compute the value of a property by

accessing multiple fields or invoking methods. However, a properly designed

get accessor performs no actions

that cause observable changes in the state of the object. end note]

Properties can be used to delay initialization of a resource until the

moment it is first referenced. [Example: For

example:

using System.IO;

public class Console

{

private static TextReader reader;

private static TextWriter writer;

private static TextWriter error;

public static TextReader In {

get {

if (reader == null) {

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

}

return reader;

}

}

public static TextWriter Out {

get {

if (writer == null) {

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

}

return writer;

}

}

public static TextWriter Error {

get {

if (error == null) {

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

}

return error;

}

}

.

}

Chapter 17 Classes

245

The Console class contains three properties, In, Out, and Error, that

represent the standard input, output, and

error devices, respectively. By exposing these members as properties, the

Console class can delay their

initialization until they are actually used. For example, upon first

referencing the Out property, as in

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

the underlying TextWriter for the output device is created. But if the

application makes no reference to the In

and Error properties, then no objects are created for those devices. end

example]

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有