A field is a member that represents a variable associated with an object or
class. A field-declaration introduces
one or more fields of a given type.
field-declaration:
attributesopt field-modifiersopt type variable-declarators ;
field-modifiers:
field-modifier
field-modifiers field-modifier
Chapter 17 Classes
221
field-modifier:
new
public
protected
internal
private
static
readonly
volatile
variable-declarators:
variable-declarator
variable-declarators , variable-declarator
variable-declarator:
identifier
identifier = variable-initializer
variable-initializer:
expression
array-initializer
A field-declaration may include a set of attributes (§24), a new modifier (
§17.2.2), a valid combination of the
four access modifiers (§17.2.3), and a static modifier (§17.4.1). In
addition, a field-declaration may include a
readonly modifier (§17.4.2) or a volatile modifier (§17.4.3), but not
both The attributes and modifiers apply
to all of the members declared by the field-declaration. It is an error for
the same modifier to appear multiple
times in a field declaration.
The type of a field-declaration specifies the type of the members
introduced by the declaration. The type is
followed by a list of variable-declarators, each of which introduces a new
member. A variable-declarator
consists of an identifier that names that member, optionally followed by an
?=? token and a variable-initializer
(§17.4.5) that gives the initial value of that member.
The type of a field must be at least as accessible as the field itself (§10.
5.4).
The value of a field is obtained in an expression using a simple-name (§14.5
.2) or a member-access (§14.5.4).
The value of a non-readonly field is modified using an assignment (§14.13).
The value of a non-readonly field
can be both obtained and modified using postfix increment and decrement
operators (§14.5.9) and prefix
increment and decrement operators (§14.6.5).
A field declaration that declares multiple fields is equivalent to multiple
declarations of single fields with the
same attributes, modifiers, and type. [Example: For example
class A
{
public static int X = 1, Y, Z = 100;
}
is equivalent to
class A
{
public static int X = 1;
public static int Y;
public static int Z = 100;
}
end example]
17.4.1 Static and instance fields
When a field declaration includes a static modifier, the fields introduced
by the declaration are static fields.
When no static modifier is present, the fields introduced by the
declaration are instance fields. Static fields
C# LANGUAGE SPECIFICATION
222
and instance fields are two of the several kinds of variables (§12)
supported by C#, and at times they are referred
to as static variables and instance variables, respectively.
A static field is not part of a specific instance; instead, it identifies
exactly one storage location. No matter how
many instances of a class are created, there is only ever one copy of a
static field for the associated application
domain.
An instance field belongs to an instance. Specifically, every instance of a
class contains a separate set of all the
instance fields of that class.
When a field is referenced in a member-access (§14.5.4) of the form E.M,
if M is a static field, E must denote a
type that has a field M, and if M is an instance field, E must denote an
instance of a type that has a field M.
The differences between static and instance members are discussed further
in §17.2.5.
17.4.2 Readonly fields
When a field-declaration includes a readonly modifier, the fields
introduced by the declaration are readonly
fields. Direct assignments to readonly fields can only occur as part of
that declaration or in an instance
constructor or static constructor in the same class. (A readonly field can
be assigned to multiple times in these
contexts.) Specifically, direct assignments to a readonly field are
permitted only in the following contexts:
? In the variable-declarator that introduces the field (by including a
variable-initializer in the declaration).
? For an instance field, in the instance constructors of the class that
contains the field declaration; for a static
field, in the static constructor of the class that contains the field
declaration. These are also the only contexts
in which it is valid to pass a readonly field as an out or ref parameter.
Attempting to assign to a readonly field or pass it as an out or ref
parameter in any other context is a
compile-time error.
17.4.2.1 Using static readonly fields for constants
A static readonly field is useful when a symbolic name for a constant value
is desired, but when the type of
the value is not permitted in a const declaration, or when the value cannot
be computed at compile-time.
[Example: In the example
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) {
red = r;
green = g;
blue = b;
}
}
the Black, White, Red, Green, and Blue members cannot be declared as const
members because their values
cannot be computed at compile-time. However, declaring them static readonly
instead has much the same
effect. end example]
17.4.2.2 Versioning of constants and static readonly fields
Constants and readonly fields have different binary versioning semantics.
When an expression references a
constant, the value of the constant is obtained at compile-time, but when
an expression references a readonly
field, the value of the field is not obtained until run-time. [Example:
Consider an application that consists of two
separate programs:
Chapter 17 Classes
223
using System;
namespace Program1
{
public class Utils
{
public static readonly int X = 1;
}
}
namespace Program2
{
class Test
{
static void Main() {
Console.WriteLine(Program1.Utils.X);
}
}
}
The Program1 and Program2 namespaces denote two programs that are compiled
separately. Because
Program1.Utils.X is declared as a static readonly field, the value output
by the Console.WriteLine
statement is not known at compile-time, but rather is obtained at run-time.
Thus, if the value of X is changed and
Program1 is recompiled, the Console.WriteLine statement will output the new
value even if Program2 isn?t
recompiled. However, had X been a constant, the value of X would have been
obtained at the time Program2 was
compiled, and would remain unaffected by changes in Program1 until Program2
is recompiled. end example]
17.4.3 Volatile fields
When a field-declaration includes a volatile modifier, the fields
introduced by that declaration are volatile
fields. For non-volatile fields, optimization techniques that reorder
instructions can lead to unexpected and
unpredictable results in multi-threaded programs that access fields without
synchronization such as that provided
by the lock-statement (§15.12). These optimizations can be performed by
the compiler, by the runtime system, or
by hardware. For volatile fields, such reordering optimizations are
restricted:
? A read of a volatile field is called a volatile read. A volatile read has
?acquire semantics?; that is, it is
guaranteed to occur prior to any references to memory that occur after it
in the instruction sequence.
? A write of a volatile field is called a volatile write. A volatile write
has ?release semantics?; that is, it is
guaranteed to happen after any memory references prior to the write
instruction in the instruction sequence.
These restrictions ensure that all threads will observe volatile writes
performed by any other thread in the order in
which they were performed. A conforming implementation is not required to
provide a single total ordering of
volatile writes as seen from all threads of execution. The type of a
volatile field must be one of the following:
? A reference-type.
? The type byte, sbyte, short, ushort, int, uint, char, float, or bool.
? An enum-type having an enum base type of byte, sbyte, short, ushort, int,
or uint.
[Example: The example
using System;
using System.Threading;
class Test
{
public static int result;
public static volatile bool finished;
static void Thread2() {
result = 143;
finished = true;
}
C# LANGUAGE SPECIFICATION
224
static void Main() {
finished = false;
// Run Thread2() in a new thread
new Thread(new ThreadStart(Thread2)).Start();
// Wait for Thread2 to signal that it has a result by setting
// finished to true.
for (;;) {
if (finished) {
Console.WriteLine("result = {0}", result);
return;
}
}
}
}
produces the output:
result = 143
In this example, the method Main starts a new thread that runs the method
Thread2. This method stores a value
into a non-volatile field called result, then stores true in the volatile
field finished. The main thread waits
for the field finished to be set to true, then reads the field result.
Since finished has been declared
volatile, the main thread must read the value 143 from the field result. If
the field finished had not been
declared volatile, then it would be permissible for the store to result to
be visible to the main thread after
the store to finished, and hence for the main thread to read the value 0
from the field result. Declaring
finished as a volatile field prevents any such inconsistency. end example]
17.4.4 Field initialization
The initial value of a field, whether it be a static field or an instance
field, is the default value (§12.2) of the
field?s type. It is not possible to observe the value of a field before
this default initialization has occurred, and a
field is thus never ?uninitialized?. [Example: The example
using System;
class Test
{
static bool b;
int i;
static void Main() {
Test t = new Test();
Console.WriteLine("b = {0}, i = {1}", b, t.i);
}
}
produces the output
b = False, i = 0
because b and i are both automatically initialized to default values. end
example]
17.4.5 Variable initializers
Field declarations may include variable-initializers. For static fields,
variable initializers correspond to
assignment statements that are executed during class initialization. For
instance fields, variable initializers
correspond to assignment statements that are executed when an instance of
the class is created.
[Example: The example
using System;
class Test
{
static double x = Math.Sqrt(2.0);
int i = 100;
string s = "Hello";
Chapter 17 Classes
225
static void Main() {
Test a = new Test();
Console.WriteLine("x = {0}, i = {1}, s = {2}", x, a.i, a.s);
}
}
produces the output
x = 1.4142135623731, i = 100, s = Hello
because an assignment to x occurs when static field initializers execute
and assignments to i and s occur when
the instance field initializers execute. end example]
The default value initialization described in §17.4.3 occurs for all
fields, including fields that have variable
initializers. Thus, when a class is initialized, all static fields in that
class are first initialized to their default values,
and then the static field initializers are executed in textual order.
Likewise, when an instance of a class is created,
all instance fields in that instance are first initialized to their default
values, and then the instance field initializers
are executed in textual order.
It is possible for static fields with variable initializers to be observed
in their default value state. [Example:
However, this is strongly discouraged as a matter of style. The example
using System;
class Test
{
static int a = b + 1;
static int b = a + 1;
static void Main() {
Console.WriteLine("a = {0}, b = {1}", a, b);
}
}
exhibits this behavior. Despite the circular definitions of a and b, the
program is valid. It results in the output
a = 1, b = 2
because the static fields a and b are initialized to 0 (the default value
for int) before their initializers are
executed. When the initializer for a runs, the value of b is zero, and so a
is initialized to 1. When the initializer
for b runs, the value of a is already 1, and so b is initialized to 2. end
example]
17.4.5.1 Static field initialization
The static field variable initializers of a class correspond to a sequence
of assignments that are executed in the
textual order in which they appear in the class declaration. If a static
constructor (§17.11) exists in the class,
execution of the static field initializers occurs immediately prior to
executing that static constructor. Otherwise,
the static field initializers are executed at an implementation-dependent
time prior to the first use of a static field
of that class. [Example: The example
using System;
class Test
{
static void Main() {
Console.WriteLine("{0} {1}", B.Y, A.X);
}
public static int f(string s) {
Console.WriteLine(s);
return 1;
}
}
class A
{
public static int X = Test.f("Init A");
}
C# LANGUAGE SPECIFICATION
226
class B
{
public static int Y = Test.f("Init B");
}
might produce either the output:
Init A
Init B
1 1
or the output:
Init B
Init A
1 1
because the execution of X’s initializer and Y’s initializer could occur
in either order; they are only constrained to
occur before the references to those fields. However, in the example:
using System;
class Test
{
static void Main() {
Console.WriteLine("{0} {1}", B.Y, A.X);
}
public static int f(string s) {
Console.WriteLine(s);
return 1;
}
}
class A
{
static A() {}
public static int X = Test.f("Init A");
}
class B
{
static B() {}
public static int Y = Test.f("Init B");
}
the output must be:
Init B
Init A
1 1
because the rules for when static constructors execute provide that B’s
static constructor (and hence B’s static field
initializers) must run before A’s static constructor and field
initializers. end example]
17.4.5.2 Instance field initialization
The instance field variable initializers of a class correspond to a
sequence of assignments that are executed
immediately upon entry to any one of the instance constructors (§17.10.2)
of that class. The variable initializers
are executed in the textual order in which they appear in the class
declaration. The class instance creation and
initialization process is described further in §17.10.
A variable initializer for an instance field cannot reference the instance
being created. Thus, it is a compile-time
error to reference this in a variable initializer, as it is a compile-time
error for a variable initializer to reference
any instance member through a simple-name. [Example: In the example
class A
{
int x = 1;
int y = x + 1; // Error, reference to instance member of this
}
Chapter 17 Classes
227
the variable initializer for y results in a compile-time error because it
references a member of the instance being
created. end example]
分享到:
相关推荐
With Firebird Maestro you can view and edit table data (including BLOB fields), export and import data to/from MS Excel, MS Access, DBF, XML, TXT, CSV and other formats, get SQL data dump and more....
4. 在Tools->Report->New/Edit Datafields中,选择COMPONENT标准属性,例如REFDES、REFDES_SORT、SYM_MIRROR、COMP_PACKAGE等。在左侧列中选择COM_用户自定义属性,例如PART_NUMBER、PART_TYPE、ASSEMBLY_OPTION等。...
Simple Structure Access 5.7.6 - Arrays of Structures 5.7.7 - Structures and Arrays as Fields of Another Structure 5.7.8 - Pointers to Structures and Arrays of Structure <br> 5.8 ...
17.4 Rayleigh-Bernard Convection 17.5 Convection in Stars 17.6 Double Diffusion Salt Fingers ix 18. Magnetohydrodynamics 18.1 Overview 18.2 Basic Equations of MHD: induction equation; dynamics;...
17.4Axiomatics .............................................. 203 Contents XIII 18 Formal Predicate Logic 209 18.1Syntactics: First-order Language ......................... 211 18.2Semantics: Σ-...
Python参考手册,官方正式版参考手册,chm版。以下摘取部分内容:Navigation index modules | next | Python » 3.6.5 Documentation » Python Documentation contents What’s New in Python ...
Chapter 19 Filtering Out Specific Fields from a GenBank File 339 19.1 EXTRACTING SELECTED PROTEIN SEQUENCES 339 19.1.1 Commented Source Code 339 19.2 EXTRACTING THE UPSTREAM REGION OF SELECTED PRO- ...
14.5.3. Retrieving Validated Fields and other Reports 14.5.3.1. Querying if the input is valid 14.5.3.2. Getting Invalid, Missing, or Unknown Fields 14.5.3.3. Getting Valid Fields 14.5.4. Using ...
1.4 Relations to Other Fields 24 1.5 How to Read This Book 25 1.5.1 Possible Course Plans Based on This Book 26 1.6 Notation 27 Part I Foundations 31 2 A Gentle Start 33 2.1 A Formal Model { The ...
Section 17.4. ESP (Encapsulating Security Payload) Section 17.5. So, Do We Need AH? Section 17.6. Comparison of Encodings Section 17.7. Easy Homework Section 17.8. Homework Chapter 18. ...
17.4用于国际互联网的ActiveX控件670 17.4.1编程问题670 17.4.2组件下载674 17.4.3授权676 第18章ADO组件678 18.1数据源类678 18.1.1 GetDataMember事件678 18.1.2对DataMember属性的支持681 18.1.3定制ActiveX Data...
17.4用于国际互联网的ActiveX控件670 17.4.1编程问题670 17.4.2组件下载674 17.4.3授权676 第18章ADO组件678 18.1数据源类678 18.1.1 GetDataMember事件678 18.1.2对DataMember属性的支持681 18.1.3定制ActiveX Data...
1 What is Liferay? 1 1.1 Building a site with Liferay Web Content . . . . . . . ....1.2 Using Liferay Portal as a collaborative platform ....1.3 Using Liferay as a social platform ....1.4 Using Liferay as a ...
2.3 Fields: A Prelude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 2.4 Review of Linear Algebra . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 2.5 Exercises . . . . . . ....
C 语言编程常见问题解答 【作者】[美]Paul S.R. Chisholm 译:张芳妮 吕 波 【出版社】清华大学... 17.4 向屏幕上写文本的最快的方法是什么? 17.5 怎样防止用户用Ctr+Break键中止程序的运行? 17.6 怎样才能只...
go程序设计语言 Contents Preface................................................................................................................................. xix PART 1—WHY LEARN GO—GETTING ...