日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

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

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

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

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

type:
value-type
reference-type
type-parameter

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

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

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

1.1 值類型

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

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 的類型時,值類型的變量才可包括 null 值。 對每一個不可以為 null 的值類型,都存在1個對應(yīng)的可以為 null 的值類型,該類型表示相同的值集加上 null 值。

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

1.1.1 System.ValueType 類型

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

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

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

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

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

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

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

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

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

1.1.4 簡單類型

C# 提供稱為簡單類型 (simple type) 的預(yù)定義結(jié)構(gòu)類型集。簡單類型通過保存字標(biāo)識,而這些保存字只是 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é)構(gòu)類型的別名,所以每一個簡單類型都具有成員。例如,int 具有在 System.Int32 中聲明的成員和從 System.Object 繼承的成員,允許使用下面的語句:

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é)構(gòu)類型的不同的地方在于,簡單類型允許某些附加的操作:

  • 大多數(shù)簡單類型允許通過編寫 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)類型的實例構(gòu)造函數(shù)來創(chuàng)建的。
  • 當(dāng)表達(dá)式的操作數(shù)都是簡單類型常量時,編譯器可以在編譯時計算表達(dá)式。這樣的表達(dá)式稱為 constant-expression(第 7.19 節(jié))。觸及其他結(jié)構(gòu)類型所定義的運算符的表達(dá)式不被視為常量表達(dá)式。
  • 通過 const 聲明可以聲明簡單類型(第 10.4 節(jié))的常量。常量不可能屬于其他結(jié)構(gòu)類型,但 static readonly 字段提供了類似的效果。
  • 觸及簡單類型的轉(zhuǎn)換可以參與由其他結(jié)構(gòu)類型定義的轉(zhuǎn)換運算符的計算,但用戶定義的轉(zhuǎn)換運算符永久不能參與其他用戶定義運算符的計算(第 6.4.3 節(jié))。

1.1.5 整型

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

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

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

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

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

1.1.6 浮點型

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

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

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

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

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

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

1.1.7 decimal 類型

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

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

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

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

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

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

1.1.8 bool 類型

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

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

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

1.1.9 枚舉類型

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

1.1.10 可以為 null 的類型

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

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

可以為 null 的類型 T? 的實例有兩個公共只讀屬性:

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

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

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

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

new T?(x)

的構(gòu)造函數(shù)將創(chuàng)建 T? 的非 null 實例,其 Value 屬性為 x。為1個給定值創(chuàng)建可以為 null 的類型的非 null 實例的進(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

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

1.2.1 類類型

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

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

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


類類型

說明

System.Object

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

System.String

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

System.ValueType

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

System.Enum

所有枚舉類型的基類。請參見第 14 章。

System.Array

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

System.Delegate

所有拜托類型的基類。請參見第 15 章。

System.Exception

所有異常類型的基類。請參見第 16 章。


1.2.2 對象類型

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

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

1.2.3 dynamic 類型

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

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

1.2.4 string 類型

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

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

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

1.2.5 接口類型

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

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

1.2.6 數(shù)組類型

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

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

1.2.7 拜托類型

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

在 C 或 C++ 中與拜托最接近的是函數(shù)指針,但函數(shù)指針只能援用靜態(tài)函數(shù),而拜托則既可以援用靜態(tài)方法,也能夠援用實例方法。在后1種情況中,拜托不但存儲了1個對該方法入口點的援用,還存儲了1個對相應(yīng)的對象實例的援用,該方法就是通過此對象實例被調(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),其中任何類型的值終究都可以按對象處理。

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 實現(xiàn)的任何 interface-type。
  • 從任何 nullable-type 到由 nullable-type 的基礎(chǔ)類型實現(xiàn)的任何 interface-type
  • 從任何 enum-type 到 System.Enum 類型。
  • 從任何具有基礎(chǔ) enum-type 的 nullable-type 到 System.Enum 類型。

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

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

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

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

sealed class Box: System.ValueType
{
T value;

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

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

int i = 123;
object box = i;

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

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

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

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

將在控制臺上輸出字符串“Box contains an int”。

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

struct Point
{
public int x, y;

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

則下面的語句

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

將在控制臺上輸出值 10,由于將 p 賦值給 box 是1個隱式裝箱操作,它將復(fù)制 p 的值。如果將 Point 聲明為 class,由于 p 和 box 將援用同1個實例,因此輸出值為 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 到實現(xiàn)了該 interface-type 的任何 non-nullable-value-type
  • 從任何 interface-type 到其基礎(chǔ)類型實現(xiàn)了該 interface-type 的任何 nullable-type
  • 從 System.Enum 類型到任何 enum-type。
  • 從 System.Enum 類型到任何具有基礎(chǔ) enum-type 的 nullable-type。

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

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

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

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

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

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

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

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

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

1.4 構(gòu)造類型

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

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

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

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)識構(gòu)造類型。當(dāng)某個類型嵌套在泛型類聲明中,并且包括該類型的聲明的實例類型被隱式用于名稱查找(第 10.3.8.6 節(jié))時,就會出現(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 類型實參

類型實參列表中的每一個實參都只是1個 type。

type-argument-list:
< type-arguments >

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

type-argument:
type

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

1.4.2 開放和封閉類型

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

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

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

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

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

1.4.3 綁定和未綁定類型

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

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

1.4.4 滿足束縛

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

  • 如果束縛為類類型、接口類型或類型形參,則假定 C 表示該束縛,并用所提供的類型實參替換出現(xiàn)在該束縛中的任何類型形參。若要滿足該束縛,必須可通過以下方式之1將類型 A 轉(zhuǎn)換為類型 C:
  • 標(biāo)識轉(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 的類型。請注意,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é))。

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

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

class Bwhere T: IEnumerable {...}

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

class E: B{...}

1.5 類型形參

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

type-parameter:
identifier

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

  • 不能直接使用類型形參聲明基類(第 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)識 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é))的束縛時,才能將 new 表達(dá)式(第 10.1.5 節(jié))與類型形參聯(lián)合使用。
  • 不能在特性中的任何位置上使用類型形參。
    • 不能在成員訪問(第 7.6.4 節(jié))或類型名稱(第 3.8 節(jié))中使用類型形參標(biāo)識靜態(tài)成員或嵌套類型。
    • 在不安全代碼中,類型形參不能用作 unmanaged-type(第 18.2 節(jié))。

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

1.6 表達(dá)式樹類型

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

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

表達(dá)式樹是匿名函數(shù)有效的內(nèi)存數(shù)據(jù)表示情勢,它使匿名函數(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á)式樹類型時用于構(gòu)造表達(dá)式樹的確切規(guī)則不在本規(guī)范的范圍以內(nèi),將另作說明。

有兩個要點需要明確指出:

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

Func del2 = exp.Compile();

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

int i1 = del(1);

int i2 = del2(1);

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

1.7 dynamic 類型

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

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

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

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

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

dynamic 類型在運行時與 object 沒有區(qū)分。

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

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: www色亚洲| 天天插天天射天天操 | 久久国产精品一区二区三区 | 亚洲一区二区三区免费在线观看 | 国产精品亚洲一区二区三区在线观看 | 久久精品久久久久电影 | 99精品视频在线观看 | 欧美日韩一区二区三区 | 不卡在线 | 91丨九色丨国产在线 | 污污视频免费网站 | 性久久久久 | 免费成人高清 | 成人av专区 | 天天摸天天操天天干 | 亚洲精品9999 | 国产成人精品一区二区三区四区 | 偷拍亚洲 | 婷婷成人精品视频在线观看 | 最新国产露脸在线观看 | 国产精品一区二区不卡 | 99在线精品免费视频九九视 | 欧美人交a欧美精品 | 免费国产在线观看 | 能直接看av的网站 | 久久国产免费视频 | 三级视频网址 | 亚洲高清福利 | 精品久久久久久久久久久久久久久久久 | 亚洲 自拍 另类 欧美 丝袜 | 91久久久久久 | 天天综合久久 | 视频一区亚洲 | 国产精品久久久一区二区三区 | 欧美久久久久久久久久 | 国产日韩欧美在线 | 亚洲国产成人av | 黄网在线| 精品视频网站 | 欧美xxxx黑人又粗又长密月 | 亚洲午夜免费视频 |