多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開源 > php教程 > C#中的數(shù)據(jù)類型

C#中的數(shù)據(jù)類型

來源:程序員人生   發(fā)布時(shí)間:2016-06-22 15:46:56 閱讀次數(shù):2802次

C# 語(yǔ)言的類型劃分為兩大類:值類型 (Value type) 和援用類型 (reference type)。值類型和援用類型都可以為泛型類型 (generic type),泛型類型采取1個(gè)或多個(gè)類型參數(shù)。類型參數(shù)可以指定值類型和援用類型。

type:
value-type
reference-type
type-parameter

第3種類型是指針,只能用在不安全代碼中。第 18.2 節(jié)對(duì)此做了進(jìn)1步的探討。

值類型與援用類型的不同的地方在于:值類型的變量直接包括其數(shù)據(jù),而援用類型的變量存儲(chǔ)對(duì)其數(shù)據(jù)的援用 (reference),后者稱為對(duì)象 (object)。對(duì)援用類型,兩個(gè)變量可能援用同1個(gè)對(duì)象,因此對(duì)1個(gè)變量的操作可能影響另外一個(gè)變量所援用的對(duì)象。對(duì)值類型,每一個(gè)變量都有自己的數(shù)據(jù)副本,對(duì)1個(gè)變量的操作不可能影響另外一個(gè)變量。

C# 的類型系統(tǒng)是統(tǒng)1的,因此任何類型的值都可以按對(duì)象處理。C# 中的每一個(gè)類型直接或間接地從 object 類類型派生,而 object 是所有類型的終究基類。援用類型的值都被視為 object 類型,被簡(jiǎn)單地當(dāng)作對(duì)象來處理。值類型的值則通過對(duì)其履行裝箱和拆箱操作(第 4.3 節(jié))按對(duì)象處理。

1.1 值類型

1個(gè)值類型或是結(jié)構(gòu)類型,或是枚舉類型。C# 提供稱為簡(jiǎn)單類型 (simple type) 的預(yù)定義結(jié)構(gòu)類型集。簡(jiǎn)單類型通過保存字標(biāo)識(shí)。

value-type:
struct-type
enum-type

struct-type:
type-name
simple-type
nullable-type

simple-type:
numeric-type
bool

numeric-type:
integral-type
floating-point-type
decimal

integral-type:
sbyte
byte
short
ushort
int
uint
long
ulong
char

floating-point-type:
float
double

nullable-type:
non-nullable-value-type   ?

non-nullable-value-type:
type

enum-type:
type-name

與援用類型的變量不同的是,僅當(dāng)該值類型是可以為 null 的類型時(shí),值類型的變量才可包括 null 值。 對(duì)每一個(gè)不可以為 null 的值類型,都存在1個(gè)對(duì)應(yīng)的可以為 null 的值類型,該類型表示相同的值集加上 null 值。

對(duì)值類型變量賦值時(shí),會(huì)創(chuàng)建所賦的值的1個(gè)副本。這不同于援用類型的變量賦值,援用類型的變量賦值復(fù)制的是援用而不是由援用標(biāo)識(shí)的對(duì)象。

1.1.1 System.ValueType 類型

所有值類型從類 System.ValueType 隱式繼承,后者又從類 object 繼承。任何類型都不可能從值類型派生,因此,所有值類型都是隱式密封的(第 10.1.1.2 節(jié))。

注意,System.ValueType 本身不是 value-type, 而是 class-type,所有 value-type 都從它自動(dòng)派生。

1.1.2 默許構(gòu)造函數(shù)

所有值類型都隱式聲明1個(gè)稱為默許構(gòu)造函數(shù) (default constructor) 的公共無參數(shù)實(shí)例構(gòu)造函數(shù)。默許構(gòu)造函數(shù)返回1個(gè)零初始化實(shí)例,它就是該值類型的默許值 (default value):

  • 對(duì)所有 simple-types,默許值是由所有位都置零的位模式產(chǎn)生的值:
  • 對(duì) sbyte、byte、byte、ushort、int、uint、long 和 ulong,默許值為 0。
  • 對(duì) char,默許值為 '\x0000'。
  • 對(duì) float,默許值為 0.0f。
  • 對(duì) double,默許值為 0.0d。
  • 對(duì) decimal,默許值為 0.0m。
  • 對(duì) bool,默許值為 false。
    • 對(duì) enum-type E,默許值為 0,該值被轉(zhuǎn)換為類型 E。
    • 對(duì) struct-type,默許值是通過將所有值類型字段設(shè)置為它們的默許值并將所有援用類型字段設(shè)置為 null 而產(chǎn)生的值。
    • 對(duì) nullable-type,默許值是1個(gè)其 HasValue 屬性為 false 且 Value 屬性未定義的實(shí)例。默許值也稱為可以為 null 的類型的 null (null value)。
    • 與任何其他實(shí)例構(gòu)造函數(shù)1樣,值類型的默許構(gòu)造函數(shù)也是用 new 運(yùn)算符調(diào)用的。出于效力緣由,實(shí)際上,沒必要故意調(diào)用它的構(gòu)造函數(shù)。在下面的示例中,變量 i 和 j 都被初始化為零。

class A
{
void F() {
     int i = 0;
     int j = new int();
}
}

由于每一個(gè)值類型都隱式地具有1個(gè)公共無形參實(shí)例構(gòu)造函數(shù),因此,1個(gè)結(jié)構(gòu)類型中不可能包括1個(gè)關(guān)于無形參構(gòu)造函數(shù)的顯式聲明。但允許結(jié)構(gòu)類型聲明參數(shù)化實(shí)例構(gòu)造函數(shù)(第 11.3.8 節(jié))。

1.1.3 結(jié)構(gòu)類型

結(jié)構(gòu)類型是1種值類型,它可以聲明常量、字段、方法、屬性、索引器、運(yùn)算符、實(shí)例構(gòu)造函數(shù)、靜態(tài)構(gòu)造函數(shù)和嵌套類型。結(jié)構(gòu)類型的聲明在第 11.1 節(jié)中說明。

1.1.4 簡(jiǎn)單類型

C# 提供稱為簡(jiǎn)單類型 (simple type) 的預(yù)定義結(jié)構(gòu)類型集。簡(jiǎn)單類型通過保存字標(biāo)識(shí),而這些保存字只是 System 命名空間中預(yù)定義結(jié)構(gòu)類型的別名,詳見下表。


..

化名的類型

sbyte

System.SByte

byte

System.Byte

short

System.Int16

ushort

System.UInt16

int

System.Int32

uint

System.UInt32

long

System.Int64

ulong

System.UInt64

char

System.Char

float

System.Single

double

System.Double

bool

System.Boolean

decimal

System.Decimal


由于簡(jiǎn)單類型是結(jié)構(gòu)類型的別名,所以每一個(gè)簡(jiǎn)單類型都具有成員。例如,int 具有在 System.Int32 中聲明的成員和從 System.Object 繼承的成員,允許使用下面的語(yǔ)句:

int i = int.MaxValue;        // System.Int32.MaxValue constant
string s = i.ToString();     // System.Int32.ToString() instance method
string t = 123.ToString();       // System.Int32.ToString() instance method

簡(jiǎn)單類型與其他結(jié)構(gòu)類型的不同的地方在于,簡(jiǎn)單類型允許某些附加的操作:

  • 大多數(shù)簡(jiǎn)單類型允許通過編寫 literals(第 2.4.4 節(jié))來創(chuàng)建值。例如,123 是類型 int 的文本,'a' 是類型 char 的文本。C# 沒有普遍地為結(jié)構(gòu)類型設(shè)置類似的以文本創(chuàng)建值的規(guī)則,所以其他結(jié)構(gòu)類型的非默許值終究總是通過這些結(jié)構(gòu)類型的實(shí)例構(gòu)造函數(shù)來創(chuàng)建的。
  • 當(dāng)表達(dá)式的操作數(shù)都是簡(jiǎn)單類型常量時(shí),編譯器可以在編譯時(shí)計(jì)算表達(dá)式。這樣的表達(dá)式稱為 constant-expression(第 7.19 節(jié))。觸及其他結(jié)構(gòu)類型所定義的運(yùn)算符的表達(dá)式不被視為常量表達(dá)式。
  • 通過 const 聲明可以聲明簡(jiǎn)單類型(第 10.4 節(jié))的常量。常量不可能屬于其他結(jié)構(gòu)類型,但 static readonly 字段提供了類似的效果。
  • 觸及簡(jiǎn)單類型的轉(zhuǎn)換可以參與由其他結(jié)構(gòu)類型定義的轉(zhuǎn)換運(yùn)算符的計(jì)算,但用戶定義的轉(zhuǎn)換運(yùn)算符永久不能參與其他用戶定義運(yùn)算符的計(jì)算(第 6.4.3 節(jié))。

1.1.5 整型

  • C# 支持 9 種整型:sbyte、byte、short、ushort、int、uint、long、ulong 和 char。整型具有以下所列的大小和取值范圍:
  • sbyte 類型表示有符號(hào) 8 位整數(shù),其值介于 ⑴28 和 127 之間。
  • byte 類型表示無符號(hào) 8 位整數(shù),其值介于 0 和 255 之間。
  • short 類型表示有符號(hào) 16 位整數(shù),其值介于 ⑶2768 和 32767 之間。
  • ushort 類型表示無符號(hào) 16 位整數(shù),其值介于 0 和 65535 之間。
  • int 類型表示有符號(hào) 32 位整數(shù),其值介于 ⑵147483648 和 2147483647 之間。
  • uint 類型表示無符號(hào) 32 位整數(shù),其值介于 0 和 4294967295 之間。
  • long 類型表示有符號(hào) 64 位整數(shù),其值介于 ⑼223372036854775808 和 9223372036854775807 之間。
  • ulong 類型表示無符號(hào) 64 位整數(shù),其值介于 0 和 18446744073709551615 之間。
  • char 類型表示無符號(hào) 16 位整數(shù),其值介于 0 和 65535 之間。char 類型的可能值集與 Unicode 字符集相對(duì)應(yīng)。雖然 char 的表示情勢(shì)與 ushort 相同,但是可以對(duì)1種類型進(jìn)行的所有計(jì)算并不是都可以對(duì)另外一種類型履行。

整型1元運(yùn)算符和2元運(yùn)算符總是對(duì)有符號(hào) 32 位精度、無符號(hào)的 32 位精度、有符號(hào) 64 位精度或無符號(hào) 64 位精度進(jìn)行計(jì)算:

  • 對(duì)1元運(yùn)算符 + 和 ~,操作數(shù)轉(zhuǎn)換為 T 類型,其中 T 是 int、uint、long 和 ulong 中第1個(gè)可以完全表示操作數(shù)的所有可能值的類型。然后用 T 類型的精度履行運(yùn)算,結(jié)果的類型是 T 類型。
  • 對(duì)1元運(yùn)算符 –,操作數(shù)轉(zhuǎn)換為類型 T,其中 T 是 int 和 long 中第1個(gè)可以完全表示操作數(shù)的所有可能值的類型。然后用 T 類型的精度履行運(yùn)算,結(jié)果的類型是 T 類型。1元運(yùn)算符 – 不能利用于類型 ulong 的操作數(shù)。
  • 對(duì) +、–、*、/、%、&、^、|、==、!=、>、<、>= 和 <= 2元運(yùn)算符,操作數(shù)轉(zhuǎn)換為類型 T,其中 T 是 int、uint、long 和 ulong 中第1個(gè)可以完全表示兩個(gè)操作數(shù)的所有可能值的類型。然后用 T 類型的精度履行運(yùn)算,運(yùn)算的結(jié)果的類型也屬于 T(對(duì)關(guān)系運(yùn)算符為 bool)。對(duì)2元運(yùn)算符,不允許1個(gè)操作數(shù)為 long 類型而另外一個(gè)操作數(shù)為 ulong 類型。
  • 對(duì)2元運(yùn)算符 << 和 >>,左操作數(shù)轉(zhuǎn)換為 T 類型,其中 T 是 int、uint、long 和 ulong 中第1個(gè)可以完全表示操作數(shù)的所有可能值的類型。然后用 T 類型的精度履行運(yùn)算,結(jié)果的類型是 T 類型。

char 類型歸類為整型類型,但它在以下兩個(gè)方面不同于其他整型:

  • 不存在從其他類型到 char 類型的隱式轉(zhuǎn)換。具體而言,即便 sbyte、byte 和 ushort 類型具有完全可以用 char 類型來表示的值范圍,也不存在從 sbyte、byte 或 ushort 到 char 的隱式轉(zhuǎn)換。
  • char 類型的常量必須寫成 character-literal 或帶有強(qiáng)迫轉(zhuǎn)換為類型 char 的 integer-literal。例如,(char)10 與 '\x000A' 是相同的。

checked 和 unchecked 運(yùn)算符和語(yǔ)句用于控制整型算術(shù)運(yùn)算和轉(zhuǎn)換(第 7.6.12 節(jié))的溢出檢查。在 checked 上下文中,溢生產(chǎn)生編譯時(shí)毛病或致使引發(fā) System.OverflowException。在 unchecked 上下文中將疏忽溢出,任何與目標(biāo)類型不匹配的高序位都被放棄。

1.1.6 浮點(diǎn)型

C# 支持兩種浮點(diǎn)型:float 和 double。float 和 double 類型用 32 位單精度和 64 位雙精度 IEEE 754 格式來表示,這些格式提供以下幾組值:

  • 正零和負(fù)零。大多數(shù)情況下,正零和負(fù)零的行動(dòng)與簡(jiǎn)單的值零相同,但某些運(yùn)算會(huì)區(qū)分對(duì)待此兩種零(第 7.8.2 節(jié))。
  • 正無窮大和負(fù)無窮大。無窮大是由非零數(shù)字被零除這樣的運(yùn)算產(chǎn)生的。例如,1.0 / 0.0 產(chǎn)生正無窮大,而 –1.0 / 0.0 產(chǎn)生負(fù)無窮大。
  • 非數(shù)字 (Not-a-Number) 值,常縮寫為 NaN。NaN 是由無效的浮點(diǎn)運(yùn)算(如零被零除)產(chǎn)生的。
  • 以 s × m × 2e 情勢(shì)表示的非零值的有限集,其中 s 為 1 或 ?1,m 和 e 由特殊的浮點(diǎn)類型肯定:對(duì) float,為 0 < m < 224 并且 ?149 ≤ e ≤ 104;對(duì) double,為 0 < m < 253 并且 ?1075 ≤ e ≤ 970。非標(biāo)準(zhǔn)化的浮點(diǎn)數(shù)被視為有效非零值。

float 類型可表示精度為 7 位、在大約 1.5 × 10?45 到 3.4 × 1038 的范圍內(nèi)的值。

double 類型可表示精度為 15 位或 16 位、在大約 5.0 × 10?324 到 1.7 × 10308 的范圍內(nèi)的值。

如果2元運(yùn)算符的1個(gè)操作數(shù)為浮點(diǎn)型,則另外一個(gè)操作數(shù)必須為整型或浮點(diǎn)型,并且運(yùn)算按下面這樣計(jì)算:

  • 如果1個(gè)操作數(shù)為整型,則該操作數(shù)轉(zhuǎn)換為與另外一個(gè)操作數(shù)的類型相同的浮點(diǎn)型。
    • 然后,如果任1操作數(shù)的類型為 double,則另外一個(gè)操作數(shù)轉(zhuǎn)換為 double。最少用 double 范圍和精度履行運(yùn)算,結(jié)果的類型為 double(對(duì)關(guān)系運(yùn)算符則為 bool)。
    • 否則,最少用 float 范圍和精度履行運(yùn)算,結(jié)果的類型為 float(對(duì)關(guān)系運(yùn)算符則為 bool)。

浮點(diǎn)運(yùn)算符(包括賦值運(yùn)算符)歷來不產(chǎn)生異常。相反,在異常情況下,浮點(diǎn)運(yùn)算產(chǎn)生零、無窮大或 NaN,以下所述:

  • 如果浮點(diǎn)運(yùn)算的結(jié)果對(duì)目標(biāo)格式太小,則運(yùn)算結(jié)果變成正零或負(fù)零。
  • 如果浮點(diǎn)運(yùn)算的結(jié)果對(duì)目標(biāo)格式太大,則運(yùn)算結(jié)果變成正無窮大或負(fù)無窮大。
    • 如果浮點(diǎn)運(yùn)算無效,則運(yùn)算的結(jié)果變成 NaN。
    • 如果浮點(diǎn)運(yùn)算的1個(gè)或兩個(gè)操作數(shù)為 NaN,則運(yùn)算的結(jié)果變成 NaN。

可以用比運(yùn)算的結(jié)果類型更高的精度來履行浮點(diǎn)運(yùn)算。例如,某些硬件結(jié)構(gòu)支持比 double 類型具有更大的范圍和精度的“extended”或“l(fā)ong double”浮點(diǎn)型,并隱式地使用這類更高精度類型履行所有浮點(diǎn)運(yùn)算。只有性能開消過大,才能使這樣的硬件結(jié)構(gòu)用“較低”的精度履行浮點(diǎn)運(yùn)算。C# 采取的是允許將更高的精度類型用于所有浮點(diǎn)運(yùn)算,而不是強(qiáng)求履行規(guī)定的精度,造成同時(shí)損失性能和精度。除傳遞更精確的結(jié)果外,這樣做很少會(huì)產(chǎn)生任何可發(fā)覺的效果。但是,在 x * y / z 情勢(shì)的表達(dá)式中,如果其中的乘法會(huì)產(chǎn)生超越 double 范圍的結(jié)果,而后面的除法使臨時(shí)結(jié)果返回到 double 范圍內(nèi),則以更大范圍的格式去計(jì)算該表達(dá)式,可能會(huì)產(chǎn)生有限值的結(jié)果(本來應(yīng)是無窮大)。

1.1.7 decimal 類型

decimal 類型是 128 位的數(shù)據(jù)類型,合適用于財(cái)務(wù)計(jì)算和貨幣計(jì)算。decimal 類型可以表示具有 28 或 29 個(gè)有效數(shù)字、從 1.0 × 10?28 到大約 7.9 × 1028 范圍內(nèi)的值。

decimal 類型的有限值集的情勢(shì)為 (–1)s × c × 10-e,其中符號(hào) s 是 0 或 1,系數(shù) c 由 0 ≤ c < 296 給定,小數(shù)位數(shù) e 滿足 0 ≤ e ≤ 28。decimal 類型不支持有符號(hào)的零、無窮大或 NaN。decimal 可用1個(gè)以 10 的冪表示的 96 位整數(shù)來表示。對(duì)絕對(duì)值小于 1.0m 的 decimal,它的值最多精確到第 28 位小數(shù)。對(duì)絕對(duì)值大于或等于 1.0m 的 decimal,它的值精確到小數(shù)點(diǎn)后第 28 或 29 位。與 float 和 double 數(shù)據(jù)類型相反,10進(jìn)制小數(shù)數(shù)字(如 0.1)可以精確地用 decimal 表示情勢(shì)來表示。在 float 和 double 表示情勢(shì)中,這類數(shù)字通常變成無窮小數(shù),使這些表示情勢(shì)更容易產(chǎn)生舍入毛病。

如果2元運(yùn)算符的1個(gè)操作數(shù)為 decimal 類型,則另外一個(gè)操作數(shù)必須為整型或 decimal 類型。如果存在1個(gè)整型操作數(shù),它將在履行運(yùn)算前轉(zhuǎn)換為 decimal。

decimal 類型值的運(yùn)算結(jié)果是這樣得出的:先計(jì)算1個(gè)精確結(jié)果(按每一個(gè)運(yùn)算符的定義保存小數(shù)位數(shù)),然后舍入以合適表示情勢(shì)。結(jié)果舍入到最接近的可表示值,當(dāng)結(jié)果一樣地接近于兩個(gè)可表示值時(shí),舍入到最小有效位數(shù)位置中為偶數(shù)的值(這稱為“銀行家舍入法”)。零結(jié)果總是包括符號(hào) 0 和小數(shù)位數(shù) 0。

如果10進(jìn)制算術(shù)運(yùn)算產(chǎn)生1個(gè)絕對(duì)值小于或等于 5 × 10⑵9 的值,則運(yùn)算結(jié)果變成零。如果 decimal 算術(shù)運(yùn)算產(chǎn)生的值對(duì) decimal 格式太大,則將引發(fā) System.OverflowException。

與浮點(diǎn)型相比,decimal 類型具有較高的精度,但取值范圍較小。因此,從浮點(diǎn)型到 decimal 的轉(zhuǎn)換可能會(huì)產(chǎn)生溢出異常,而從 decimal 到浮點(diǎn)型的轉(zhuǎn)換則可能致使精度損失。由于這些緣由,在浮點(diǎn)型和 decimal 之間不存在隱式轉(zhuǎn)換,如果沒有顯式地標(biāo)出強(qiáng)迫轉(zhuǎn)換,就不可能在同1表達(dá)式中同時(shí)使用浮點(diǎn)操作數(shù)和 decimal 操作數(shù)。

1.1.8 bool 類型

bool 類型表示布爾邏輯量。bool 類型的可能值為 true 和 false。

在 bool 和其他類型之間不存在標(biāo)準(zhǔn)轉(zhuǎn)換。具體而言,bool 類型與整型截然不同,不能用 bool 值代替整數(shù)值,反之亦然。

在 C 和 C++ 語(yǔ)言中,零整數(shù)或浮點(diǎn)值或 null 指針可以轉(zhuǎn)換為布爾值 false,非零整數(shù)或浮點(diǎn)值或非 null 指針可以轉(zhuǎn)換為布爾值 true。在 C# 中,這類轉(zhuǎn)換是通過顯式地將整數(shù)或浮點(diǎn)值與零進(jìn)行比較,或顯式地將對(duì)象援用與 null 進(jìn)行比較來完成的。

1.1.9 枚舉類型

枚舉類型是具有命名常量的獨(dú)特的類型。每一個(gè)枚舉類型都有1個(gè)基礎(chǔ)類型,該基礎(chǔ)類型必須為 byte、sbyte、short、ushort、int、uint、long 或 ulong。枚舉類型的值集和它的基礎(chǔ)類型的值集相同。枚舉類型的值其實(shí)不只限于那些命名常量的值。枚舉類型是通過枚舉聲明(第 14.1 節(jié))定義的。

1.1.10 可以為 null 的類型

可以為 null 的類型可以表示其基礎(chǔ)類型 (underlying type) 的所有值和1個(gè)額外的 null 值。可以為 null 的類型寫作 T?,其中 T 是基礎(chǔ)類型。此語(yǔ)法是 System.Nullable的簡(jiǎn)寫情勢(shì),這兩種情勢(shì)可以互換使用。

相反,不可以為 null 的值類型 (non-nullable value type) 可以是除 System.Nullable及其簡(jiǎn)寫情勢(shì)T?(對(duì)任何類型的 T)以外的任何值類型,加上束縛為不可以為 null 的值類型的任何類型參數(shù)(即具有 struct 束縛的任何類型參數(shù))。System.Nullable類型指定 T 的值類型束縛(第 10.1.5 節(jié)),這意味著可以為 null 的類型的基礎(chǔ)類型可以是任何不可以為 null 的值類型。可以為 null 的類型的基礎(chǔ)類型不能是可以為 null 的類型或援用類型。例如,int?? 和 string? 是無效類型。

可以為 null 的類型 T? 的實(shí)例有兩個(gè)公共只讀屬性:

  • 類型為 bool 的 HasValue 屬性
  • 類型為 T 的 Value 屬性

HasValue 為 true 的實(shí)例稱為非 null。非 null 實(shí)例包括1個(gè)已知值,可通過 Value 返回該值。

HasValue 為 false 的實(shí)例稱為 null。null 實(shí)例有1個(gè)不肯定的值。嘗試讀取 null 實(shí)例的 Value 將致使引發(fā) System.InvalidOperationException。訪問可以為 null 的實(shí)例的 Value 屬性的進(jìn)程稱作解包 (unwrapping)。

除默許構(gòu)造函數(shù)以外,每一個(gè)可以為 null 的類型 T? 都有1個(gè)具有類型為 T 的單個(gè)實(shí)參的公共構(gòu)造函數(shù)。例如,給定1個(gè)類型為 T 的值 x,調(diào)用形如

new T?(x)

的構(gòu)造函數(shù)將創(chuàng)建 T? 的非 null 實(shí)例,其 Value 屬性為 x。為1個(gè)給定值創(chuàng)建可以為 null 的類型的非 null 實(shí)例的進(jìn)程稱作包裝 (wrapping)。

從 null 文本轉(zhuǎn)換為 T?(第 6.1.5 節(jié))和從 T 轉(zhuǎn)換為 T?(第 6.1.4 節(jié))可以使用隱式轉(zhuǎn)換。

1.2 援用類型

援用類型是類類型、接口類型、數(shù)組類型或拜托類型。

reference-type:
class-type
interface-type
array-type
delegate-type

class-type:
type-name
object
dynamic
string

interface-type:
type-name

array-type:
non-array-type   rank-specifiers

non-array-type:
type

rank-specifiers:
rank-specifier
rank-specifiers   rank-specifier

rank-specifier:
[   dim-separatorsopt   ]

 dim-separators:
,
dim-separators   ,

delegate-type:
type-name

援用類型值是對(duì)該類型的某個(gè)實(shí)例 (instance) 的1個(gè)援用,后者稱為對(duì)象 (object)。null 值比較特別,它兼容于所有援用類型,用來表示“沒有被援用的實(shí)例”。

1.2.1 類類型

類類型定義包括數(shù)據(jù)成員、函數(shù)成員和嵌套類型的數(shù)據(jù)結(jié)構(gòu),其中數(shù)據(jù)成員包括常量和字段,函數(shù)成員包括方法、屬性、事件、索引器、運(yùn)算符、實(shí)例構(gòu)造函數(shù)、析構(gòu)函數(shù)和靜態(tài)構(gòu)造函數(shù)。類類型支持繼承,繼承是派生類可用來擴(kuò)大和專門化基類的1種機(jī)制。類類型的實(shí)例是用 object-creation-expressions(第 7.6.10.1 節(jié))創(chuàng)建的。

有關(guān)類類型的介紹詳見第 10 章。

某些預(yù)定義類類型在 C# 語(yǔ)言中有特殊含義,以下表所示。


類類型

說明

System.Object

所有其他類型的終究基類。請(qǐng)參見第 4.2.2 節(jié)。

System.String

C# 語(yǔ)言的字符串類型。請(qǐng)參見第 4.2.4 節(jié)。

System.ValueType

所有值類型的基類。請(qǐng)參見第 4.1.1 節(jié)。

System.Enum

所有枚舉類型的基類。請(qǐng)參見第 14 章。

System.Array

所有數(shù)組類型的基類。請(qǐng)參見第 12 章。

System.Delegate

所有拜托類型的基類。請(qǐng)參見第 15 章。

System.Exception

所有異常類型的基類。請(qǐng)參見第 16 章。


1.2.2 對(duì)象類型

object 類類型是所有其他類型的終究基類。C# 中的每種類型都是直接或間接從 object 類類型派生的。

關(guān)鍵字 object 只是預(yù)定義類 System.Object 的別名。

1.2.3 dynamic 類型

dynamic 類型與 object 1樣,可以援用任何對(duì)象。在將運(yùn)算符利用于 dynamic 類型的表達(dá)式時(shí),其解析會(huì)推延到程序運(yùn)行時(shí)進(jìn)行。因此,如果運(yùn)算符不能合法地利用于援用的對(duì)象,在編譯進(jìn)程中不會(huì)報(bào)告任何毛病。而是在運(yùn)行時(shí)解析運(yùn)算符失敗時(shí),會(huì)引發(fā)異常。

在第 4.7 節(jié)中進(jìn)1步介紹了動(dòng)態(tài)類型,在第 7.2.2 節(jié)中進(jìn)1步介紹了動(dòng)態(tài)綁定。

1.2.4 string 類型

string 類型是直接從 object 繼承的密封類類型。string 類的實(shí)例表示 Unicode 字符串。

string 類型的值可以寫為字符串(第 2.4.4.5 節(jié))。

關(guān)鍵字 string 只是預(yù)定義類 System.String 的別名。

1.2.5 接口類型

1個(gè)接口定義1個(gè)協(xié)議。實(shí)現(xiàn)某接口的類或結(jié)構(gòu)必須遵照該接口定義的協(xié)議。1個(gè)接口可以從多個(gè)基接口繼承,而1個(gè)類或結(jié)構(gòu)可以實(shí)現(xiàn)多個(gè)接口。

有關(guān)接口類型的介紹詳見第 13 章。

1.2.6 數(shù)組類型

數(shù)組是1種數(shù)據(jù)結(jié)構(gòu),它包括可通過計(jì)算索引訪問的零個(gè)或更多個(gè)變量。數(shù)組中包括的變量(又稱數(shù)組的元素)具有相同的類型,該類型稱為數(shù)組的元素類型。

有關(guān)數(shù)組類型的介紹詳見第 12 章。

1.2.7 拜托類型

拜托是援用1個(gè)或多個(gè)方法的數(shù)據(jù)結(jié)構(gòu)。對(duì)實(shí)例方法,拜托還可援用實(shí)例方法對(duì)應(yīng)的對(duì)象實(shí)例。

在 C 或 C++ 中與拜托最接近的是函數(shù)指針,但函數(shù)指針只能援用靜態(tài)函數(shù),而拜托則既可以援用靜態(tài)方法,也能夠援用實(shí)例方法。在后1種情況中,拜托不但存儲(chǔ)了1個(gè)對(duì)該方法入口點(diǎn)的援用,還存儲(chǔ)了1個(gè)對(duì)相應(yīng)的對(duì)象實(shí)例的援用,該方法就是通過此對(duì)象實(shí)例被調(diào)用的。

有關(guān)拜托類型的介紹詳見第 15 章。

1.3 裝箱和拆箱

裝箱和拆箱的概念是 C# 的類型系統(tǒng)的核心。它在 value-typesreference-types 之間架起了1座橋梁,使得任何 value-type 的值都可以轉(zhuǎn)換為 object 類型的值,反過來轉(zhuǎn)換也能夠。裝箱和拆箱使我們能夠統(tǒng)1地來考察類型系統(tǒng),其中任何類型的值終究都可以按對(duì)象處理。

1.3.1 裝箱轉(zhuǎn)換

裝箱轉(zhuǎn)換允許將 value-type 隱式轉(zhuǎn)換為 reference-type。存在以下裝箱轉(zhuǎn)換:

  • 從任何 value-type 到 object 類型。
  • 從任何 value-type 到 System.ValueType 類型。
  • 從任何 non-nullable-value-type 到 value-type 實(shí)現(xiàn)的任何 interface-type。
  • 從任何 nullable-type 到由 nullable-type 的基礎(chǔ)類型實(shí)現(xiàn)的任何 interface-type
  • 從任何 enum-type 到 System.Enum 類型。
  • 從任何具有基礎(chǔ) enum-type 的 nullable-type 到 System.Enum 類型。

請(qǐng)注意,對(duì)類型形參進(jìn)行隱式轉(zhuǎn)換將以裝箱轉(zhuǎn)換的情勢(shì)履行(如果在運(yùn)行時(shí)它最后從值類型轉(zhuǎn)換到援用類型(第 6.1.10 節(jié)))。

non-nullable-value-type 的1個(gè)值裝箱包括以下操作:分配1個(gè)對(duì)象實(shí)例,然后將 non-nullable-value-type 的值復(fù)制到該實(shí)例中。

對(duì) nullable-type 的值裝箱時(shí),如果該值為 null 值(HasValue 為 false),將產(chǎn)生1個(gè) null 援用;否則將產(chǎn)生對(duì)基礎(chǔ)值解包和裝箱的結(jié)果。

最能說明 non-nullable-value-type 的值的實(shí)際裝箱進(jìn)程的辦法是,假想有1個(gè)泛型裝箱類 (boxing class),其行動(dòng)與下面聲明的類相似:

sealed class Box: System.ValueType
{
T value;

public Box(T t) {
     value = t;
}
}

T 類型值 v 的裝箱進(jìn)程現(xiàn)在包括履行表達(dá)式 new Box(v) 和將結(jié)果實(shí)例作為 object 類型的值返回。因此,下面的語(yǔ)句

int i = 123;
object box = i;

在概念上相當(dāng)于

int i = 123;
object box = new Box(i);

實(shí)際上,像上面這樣的 Box裝箱類其實(shí)不存在,并且裝箱值的動(dòng)態(tài)類型也不會(huì)真的屬于1個(gè)類類型。相反,T 類型的裝箱值屬于動(dòng)態(tài)類型 T,若用 is 運(yùn)算符來檢查動(dòng)態(tài)類型,也僅能援用類型 T。例如,

int i = 123;
object box = i;
if (box is int) {
Console.Write("Box contains an int");
}

將在控制臺(tái)上輸出字符串“Box contains an int”。

裝箱轉(zhuǎn)換隱含著復(fù)制1份 待裝箱的值。這不同于從 reference-type 到 object 類型的轉(zhuǎn)換,在后1種轉(zhuǎn)換中,轉(zhuǎn)換后的值繼續(xù)援用同1實(shí)例,只是將它當(dāng)作派生程度較小的 object 類型而已。例如,給定下面的聲明

struct Point
{
public int x, y;

public Point(int x, int y) {
     this.x = x;
     this.y = y;
}
}

則下面的語(yǔ)句

Point p = new Point(10, 10);
object box = p;
p.x = 20;
Console.Write(((Point)box).x);

將在控制臺(tái)上輸出值 10,由于將 p 賦值給 box 是1個(gè)隱式裝箱操作,它將復(fù)制 p 的值。如果將 Point 聲明為 class,由于 p 和 box 將援用同1個(gè)實(shí)例,因此輸出值為 20。

1.3.2 拆箱轉(zhuǎn)換

取消裝箱轉(zhuǎn)換允許將 reference-type 顯式轉(zhuǎn)換為 value-type。存在以下拆箱轉(zhuǎn)換:

  • 從 object 類型到任何 value-type。
  • 從 System.ValueType 類型到任何 value-type。
  • 從任何 interface-type 到實(shí)現(xiàn)了該 interface-type 的任何 non-nullable-value-type
  • 從任何 interface-type 到其基礎(chǔ)類型實(shí)現(xiàn)了該 interface-type 的任何 nullable-type
  • 從 System.Enum 類型到任何 enum-type。
  • 從 System.Enum 類型到任何具有基礎(chǔ) enum-type 的 nullable-type。

請(qǐng)注意,到類型形參的顯式轉(zhuǎn)換將以取消裝箱轉(zhuǎn)換的情勢(shì)履行(如果在運(yùn)行時(shí)它結(jié)束從援用類型到值類型(第 6.2.6 節(jié))的轉(zhuǎn)換)。

對(duì) non-nullable-value-type 取消裝箱的操作包括以下步驟:首先檢查對(duì)象實(shí)例是不是是給定 non-nullable-value-type 的裝箱值,然后將該值從實(shí)例中復(fù)制出來。

對(duì) nullable-type 取消裝箱在源操作數(shù)為 null 時(shí)會(huì)產(chǎn)生 nullable-type 的 null 值;否則將產(chǎn)生從對(duì)象實(shí)例到 nullable-type 的基礎(chǔ)類型的取消裝箱的包裝結(jié)果。

參照前1節(jié)中關(guān)于假想的裝箱類的描寫,從對(duì)象 box 到 value-type T 的取消裝箱轉(zhuǎn)換包括履行表達(dá)式 ((Box)box).value。因此,下面的語(yǔ)句

object box = 123;
int i = (int)box;

在概念上相當(dāng)于

object box = new Box(123);
int i = ((Box)box).value;

為使針對(duì)給定 non-nullable-value-type 的取消裝箱轉(zhuǎn)換在運(yùn)行時(shí)獲得成功,源操作數(shù)的值必須是對(duì)該 non-nullable-value-type 的裝箱值的援用。如果源操作數(shù)為 null,則將引發(fā) System.NullReferenceException。如果源操作數(shù)是對(duì)不兼容對(duì)象的援用,則將引發(fā) System.InvalidCastException。

為使針對(duì)給定 nullable-type 的取消裝箱轉(zhuǎn)換在運(yùn)行時(shí)獲得成功,源操作數(shù)的值必須是 null 或是對(duì)該 nullable-type 的基礎(chǔ) non-nullable-value-type 的裝箱值的援用。如果源操作數(shù)是對(duì)不兼容對(duì)象的援用,則將引發(fā) System.InvalidCastException。

1.4 構(gòu)造類型

泛型類型聲明本身表示未綁定的泛型類型 (unbound generic type),它通過利用類型實(shí)參 (type argument) 被用作構(gòu)成許多不同類型的“藍(lán)圖”。類型實(shí)參編寫在緊跟在泛型類型的名稱后面的尖括號(hào)(< 和 >)中。最少包括1個(gè)類型實(shí)參的類型稱為構(gòu)造類型 (constructed type)。構(gòu)造類型可以在語(yǔ)言中能夠出現(xiàn)類型名的大多數(shù)地方使用。未綁定的泛型類型只能在 typeof-expression(第 7.6.11 節(jié))中使用。

構(gòu)造類型還可以在表達(dá)式中用作簡(jiǎn)單名稱(第 7.6.2 節(jié))或在訪問成員時(shí)使用(第 7.6.4 節(jié))。

在計(jì)算 namespace-or-type-name 時(shí),僅斟酌具有正確數(shù)目的類型形參的泛型類型。因此,可使用同1個(gè)標(biāo)識(shí)符標(biāo)識(shí)不同的類型,條件是那些類型具有不同數(shù)目的類型形參。當(dāng)在同1程序中混合使用泛型和非泛型類時(shí),這是很有用的:

namespace Widgets
{
class Queue {...}
class Queue{...}
}

namespace MyApplication
{
using Widgets;

class X
{
     Queue q1;         // Non-generic Widgets.Queue
     Queueq2;       // Generic Widgets.Queue
}
}

即便未直接指定類型形參,type-name 也能夠標(biāo)識(shí)構(gòu)造類型。當(dāng)某個(gè)類型嵌套在泛型類聲明中,并且包括該類型的聲明的實(shí)例類型被隱式用于名稱查找(第 10.3.8.6 節(jié))時(shí),就會(huì)出現(xiàn)這類情況:

class Outer
{
public class Inner {...}

public Inner i;             // Type of i is Outer.Inner
}

在不安全代碼中,構(gòu)造類型不能用作 unmanaged-type(第 18.2 節(jié))。

1.4.1 類型實(shí)參

類型實(shí)參列表中的每一個(gè)實(shí)參都只是1個(gè) type。

type-argument-list:
< type-arguments >

type-arguments:
type-argument
type-arguments   ,   type-argument

type-argument:
type

在不安全代碼(第 18 章)中,type-argument 不可以是指針類型。每一個(gè)類型實(shí)參都必須滿足對(duì)應(yīng)的類型形參上的所有束縛(第 10.1.5 節(jié))。

1.4.2 開放和封閉類型

所有類型都可歸類為開放類型 (open type) 或封閉類型 (closed type)。開放類型是包括類型形參的類型。更明確地說:

  • 類型形參定義開放類型。
  • 當(dāng)且僅當(dāng)數(shù)組元素類型是開放類型時(shí),該數(shù)組類型才是開放類型。
  • 當(dāng)且僅當(dāng)構(gòu)造類型的1個(gè)或多個(gè)類型實(shí)參為開放類型時(shí),該構(gòu)造類型才是開放類型。當(dāng)且僅當(dāng)構(gòu)造的嵌套類型的1個(gè)或多個(gè)類型實(shí)參或其包括類型的類型實(shí)參為開放類型時(shí),該構(gòu)造的嵌套類型才是開放類型。

封閉類型是不屬于開放類型的類型。

在運(yùn)行時(shí),泛型類型聲明中的所有代碼都在1個(gè)封閉構(gòu)造類型的上下文中履行,這個(gè)封閉構(gòu)造類型是通過將類型實(shí)參利用該泛型聲明來創(chuàng)建的。泛型類型中的每一個(gè)類型形參都綁定到特定的運(yùn)行時(shí)類型。所有語(yǔ)句和表達(dá)式的運(yùn)行時(shí)處理都始終使用封閉類型,開放類型僅出現(xiàn)在編譯時(shí)處理進(jìn)程中。

每一個(gè)封閉構(gòu)造類型都有自己的靜態(tài)變量集,任何其他封閉構(gòu)造類型都不會(huì)同享這些變量。由于開放類型在運(yùn)行時(shí)其實(shí)不存在,因此不存在與開放類型關(guān)聯(lián)的靜態(tài)變量。如果兩個(gè)封閉構(gòu)造類型是從相同的未綁定泛型類型構(gòu)造的,并且它們的對(duì)應(yīng)類型實(shí)參屬于相同類型,則這兩個(gè)封閉構(gòu)造類型是相同類型。

1.4.3 綁定和未綁定類型

術(shù)語(yǔ)未綁定類型 (unbound type) 是指非泛型類型或未綁定的泛型類型。術(shù)語(yǔ)綁定類型 (bound type) 是指非泛型類型或構(gòu)造類型。

未綁定類型是指類型聲明所聲明的實(shí)體。未綁定泛型類型本身不是1種類型,不能用作變量、參數(shù)或返回值的類型,也不能用作基類型。可以援用未綁定泛型類型的唯1構(gòu)造是 typeof 表達(dá)式(第 7.6.11 節(jié))。

1.4.4 滿足束縛

每當(dāng)援用構(gòu)造類型或泛型方法時(shí),都會(huì)根據(jù)泛型類型或方法(第 10.1.5 節(jié))上聲明的類型形參束縛對(duì)所提供的類型實(shí)參進(jìn)行檢查。對(duì)每一個(gè) where 子句,將根據(jù)每一個(gè)束縛檢查與命名的類型形參相對(duì)應(yīng)的類型實(shí)參 A,以下所示:

  • 如果束縛為類類型、接口類型或類型形參,則假定 C 表示該束縛,并用所提供的類型實(shí)參替換出現(xiàn)在該束縛中的任何類型形參。若要滿足該束縛,必須可通過以下方式之1將類型 A 轉(zhuǎn)換為類型 C:
  • 標(biāo)識(shí)轉(zhuǎn)換(第 6.1.1 節(jié))
  • 隱式援用轉(zhuǎn)換(第 6.1.6 節(jié))
  • 裝箱轉(zhuǎn)換(第 6.1.7 節(jié))— 條件是類型 A 為不可以為 null 的值類型。
  • 從類型形參 A 到 C 的隱式援用、裝箱或類型形參轉(zhuǎn)換。
    • 如果束縛為援用類型束縛 (class) 則類型 A 必須滿足以下條件之1:
    • A 為接口類型、類類型、拜托類型或數(shù)組類型。注意,System.ValueType 和 System.Enum 是滿足此束縛的援用類型。
    • A 是已知為援用類型的類型形參(第 10.1.5 節(jié))。
      • 如果束縛為值類型束縛 (struct) 則類型 A 必須滿足以下條件之1:
      • A 為結(jié)構(gòu)類型或枚舉類型,但不是可以為 null 的類型。請(qǐng)注意,System.ValueType 和 System.Enum 是不滿足此束縛的援用類型。
      • A 為具有值類型束縛的類型形參(第 10.1.5 節(jié))。
        • 如果束縛為構(gòu)造函數(shù)束縛 new(),則類型 A 1定不能為 abstract,并且必須具有公共無形參構(gòu)造函數(shù)。如果以下條件之1成立,則滿足此條件:
        • A 為值類型,由于所有值類型都具有公共默許構(gòu)造函數(shù)(第 4.1.2 節(jié))。
        • A 為具有構(gòu)造函數(shù)束縛的類型形參(第 10.1.5 節(jié))。
        • A 為具有值類型束縛的類型形參(第 10.1.5 節(jié))。
        • A 是不為 abstract 并且包括顯式聲明的無參數(shù) public 構(gòu)造函數(shù)的類。
        • A 不為 abstract,并且具有默許構(gòu)造函數(shù)(第 10.11.4 節(jié))。

如果給定的類型實(shí)參未滿足1個(gè)或多個(gè)類型形參的束縛,則會(huì)產(chǎn)生編譯時(shí)毛病。

由于類型形參未被繼承,因此束縛也從不被繼承。在下面的示例中,T 需要指定其類型形參 T 上的束縛,以便 T 滿足基類 B所施加的束縛。相反,類 E 不需要指定束縛,由于對(duì)任何 T,List都實(shí)現(xiàn) IEnumerable。

class Bwhere T: IEnumerable {...}

class D: Bwhere T: IEnumerable {...}

class E: B{...}

1.5 類型形參

類型形參是指定形參在運(yùn)行時(shí)要綁定到的值類型或援用類型的標(biāo)識(shí)符。

type-parameter:
identifier

由于類型形參可以使用許多不同的實(shí)際類型實(shí)參進(jìn)行實(shí)例化,因此類型形參具有與其他類型略微不同的操作和限制。這包括:

  • 不能直接使用類型形參聲明基類(第 10.2.4 節(jié))或接口(第 13.1.3 節(jié))。
  • 類型形參上的成員查找規(guī)則取決于利用到該類型形參的束縛(如果有)。這將在第 7.4 節(jié)中詳細(xì)描寫。
  • 類型形參的可用轉(zhuǎn)換取決于利用到該類型形參的束縛(如果有)。這將在第 6.1.10 和 6.2.6 節(jié)中詳細(xì)描寫。
  • 如果事前不知道由類型形參給出的類型是援用類型(第 6.1.10 節(jié)),不能將標(biāo)識(shí) null 轉(zhuǎn)換為該類型。不過,可以改成使用 default 表達(dá)式(第 7.6.13 節(jié))。另外,具有由類型形參給出的類型的值可以 使用 == 和 != 與 null 進(jìn)行比較(第 7.10.6 節(jié)),除非該類型形參具有值類型束縛。
  • 僅當(dāng)類型形參受 constructor-constraint 或值類型束縛(第 7.6.10.1 節(jié))的束縛時(shí),才能將 new 表達(dá)式(第 10.1.5 節(jié))與類型形參聯(lián)合使用。
  • 不能在特性中的任何位置上使用類型形參。
    • 不能在成員訪問(第 7.6.4 節(jié))或類型名稱(第 3.8 節(jié))中使用類型形參標(biāo)識(shí)靜態(tài)成員或嵌套類型。
    • 在不安全代碼中,類型形參不能用作 unmanaged-type(第 18.2 節(jié))。

作為類型,類型形參純潔是1個(gè)編譯時(shí)構(gòu)造。在運(yùn)行時(shí),每一個(gè)類型形參都綁定到1個(gè)運(yùn)行時(shí)類型,運(yùn)行時(shí)類型是通過向泛型類型聲明提供類型實(shí)參來指定的。因此,使用類型形參聲明的變量的類型在運(yùn)行時(shí)將是封閉構(gòu)造類型(第 4.4.2 節(jié))。觸及類型形參的所有語(yǔ)句和表達(dá)式的運(yùn)行時(shí)履行都使用作為該形參的類型實(shí)參提供的實(shí)際類型。

1.6 表達(dá)式樹類型

表達(dá)式樹 (Expression tree) 允許匿名函數(shù)表示為數(shù)據(jù)結(jié)構(gòu)而不是可履行代碼。表達(dá)式樹是 System.Linq.Expressions.Expression情勢(shì)的表達(dá)式樹類型 (expression tree type) 的值,其中 D 是任何拜托類型。對(duì)本規(guī)范的其余部份,我們將使用簡(jiǎn)寫情勢(shì) Expression援用這些類型。

如果存在從匿名函數(shù)到拜托類型 D 的轉(zhuǎn)換,則也存在到表達(dá)式樹類型 Expression的轉(zhuǎn)換。不過,匿名函數(shù)到拜托類型的轉(zhuǎn)換會(huì)生成1個(gè)援用該匿名函數(shù)的可履行代碼的拜托,而到表達(dá)式樹類型的轉(zhuǎn)換則會(huì)創(chuàng)建該匿名函數(shù)的表達(dá)式樹表示情勢(shì)。

表達(dá)式樹是匿名函數(shù)有效的內(nèi)存數(shù)據(jù)表示情勢(shì),它使匿名函數(shù)的結(jié)構(gòu)變得透明和明晰。

與拜托類型 D 1樣,Expression具有與 D 相同的參數(shù)和返回類型。

下面的示例將匿名函數(shù)表示為可履行代碼和表達(dá)式樹。由于存在到 Func 的轉(zhuǎn)換,所以也存在到 Expression> 的轉(zhuǎn)換:

Func del = x => x + 1;                   // Code

Expression> exp = x => x + 1;       // Data

進(jìn)行上面的賦值以后,拜托 del 援用返回 x + 1 的方法,表達(dá)式目錄樹 exp 援用描寫表達(dá)式 x => x + 1 的數(shù)據(jù)結(jié)構(gòu)。

泛型類型 Expression的準(zhǔn)肯定義和當(dāng)將匿名函數(shù)轉(zhuǎn)換為表達(dá)式樹類型時(shí)用于構(gòu)造表達(dá)式樹的確切規(guī)則不在本規(guī)范的范圍以內(nèi),將另作說明。

有兩個(gè)要點(diǎn)需要明確指出:

  • 并不是所有匿名函數(shù)都能表示為表達(dá)式樹。例如,具有語(yǔ)句體的匿名函數(shù)和包括賦值表達(dá)式的匿名函數(shù)就不能表示為表達(dá)式樹。在這些情況下,轉(zhuǎn)換仍存在,但在編譯時(shí)將失敗。
  • Expression提供1個(gè)實(shí)例方法 Compile,該方法產(chǎn)生1個(gè)類型為 D 的拜托:

Func del2 = exp.Compile();

調(diào)用此拜托將致使履行表達(dá)式樹所表示的代碼。因此,根據(jù)上面的定義,del 和 del2 等效,而且下面的兩個(gè)語(yǔ)句也將等效:

int i1 = del(1);

int i2 = del2(1);

              履行此代碼后,i1 和 i2 的值都為 2。

1.7 dynamic 類型

dynamic 類型在 C# 中具有特殊含義。其用處在于允許進(jìn)行動(dòng)態(tài)綁定(在第 7.2.2 節(jié)中進(jìn)行了詳細(xì)介紹)。

dynamic 被視為與 object 相同,除以下這些方面:

  • 對(duì) dynamic 類型的表達(dá)式進(jìn)行的運(yùn)算可以動(dòng)態(tài)綁定(第 7.2.2 節(jié))。
  • 類型推斷(第 7.5.2 節(jié))在 dynamic 和 object 都是候選項(xiàng)時(shí),會(huì)優(yōu)先斟酌前者。

由于此等效性,因此存在以下情況:

  • object 與 dynamic 之間,和對(duì)在將 dynamic 替換為 object 時(shí)相同的構(gòu)造類型之間,存在隱式標(biāo)識(shí)轉(zhuǎn)換
  • 與 object 之間的隱式和顯式轉(zhuǎn)換也適用于 dynamic。
  • 在將 dynamic 替換為 object 時(shí)相同的方法簽名視為是相同的簽名

dynamic 類型在運(yùn)行時(shí)與 object 沒有區(qū)分。

dynamic 類型的表達(dá)式稱為動(dòng)態(tài)表達(dá)式 (dynamic expression)。

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 欧美小说图片视频 | 中文字幕在线播放第一页 | 欧美激情伦妇在线观看 | 日本亚洲网站 | 欧美videos日本hd| 福利免费在线 | 中文字幕第6页 | 毛片传媒 | 欧美性猛交xxxx乱大交高清 | 亚洲精国产一区二区三区 | free性video西欧极品 | 亚洲天堂2013 | 久久机热这里只有精品 | 欧美日韩你懂的 | 亚洲人成在线播放网站 | 欧美1区二区三区公司 | 亚洲精品456播放 | 久久国产综合精品欧美 | 8av国产精品爽爽ⅴa在线观看 | 国产v综合v亚洲欧美大另类 | 国产欧美精品区一区二区三区 | 夜夜狠操| 欧美色涩 | 国产中的精品一区的 | 欧美性猛交99久久久久99 | 亚洲成人av | 亚洲天堂高清 | 最近中文字幕高清字幕6 | 欧美一区二区三区不卡免费观看 | 尤物视频网站在线 | 亚洲天堂久久精品 | 黄色免费网站网址 | 日本护士和病人xxxxx | www网站在线观看 | 免费一级做a爰片性色毛片 免费一看一级毛片 | 狠狠躁 | 中文字幕在亚洲第一在线 | 亚洲视频h| 免费观看亚洲 | 国产做出在线 | 传媒麻豆 | 午夜看片网站 |