內建參考型別 (C# 參考)Built-in reference types (C# reference)
C# 有數種內建參考型別。C# has a number of built-in reference types. 它們具有關鍵字或運算子,是 .NET 程式庫中類型的同義字。They have keywords or operators that are synonyms for a type in the .NET library.
物件型別The object type
object
類型是 System.Object 在 .NET 中的別名。The object
type is an alias for System.Object in .NET. 在 C# 的統一型別系統中,所有類型 (預先定義和使用者定義的、參考型別和實值型別) 都會直接或間接繼承自 System.Object。In the unified type system of C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from System.Object. 您可以將任何型別的值指派給 object
型別的變數。You can assign values of any type to variables of type object
. 任何 object
變數都可以使用常值 null
指派給其預設值。Any object
variable can be assigned to its default value using the literal null
. 當實值型別的變數轉換成物件時,即稱之為 Boxed。When a variable of a value type is converted to object, it is said to be boxed. 當型別的變數轉換成實 object
值型別時,就表示它是取消 裝箱。When a variable of type object
is converted to a value type, it is said to be unboxed. 如需詳細資訊,請參閱 Boxing 和 Unboxing。For more information, see Boxing and Unboxing.
字串型別The string type
string
類型代表零或多個 Unicode 字元序列。The string
type represents a sequence of zero or more Unicode characters. string
是 System.String 在 .NET 中的別名。string
is an alias for System.String in .NET.
雖然 string
是參考型別,但是會定義等號比較運算子 ==
和 !=
來比較 string
物件的值,而不是參考。Although string
is a reference type, the equality operators ==
and !=
are defined to compare the values of string
objects, not references. 這樣會以更直覺的方式來測試字串是否相等。This makes testing for string equality more intuitive. 例如:For example:
string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine(object.ReferenceEquals(a, b));
這會依序顯示 "True" 和 "False",因為字串的內容相等,但 a
和 b
未參照相同的字串執行個體。This displays "True" and then "False" because the content of the strings are equivalent, but a
and b
do not refer to the same string instance.
+ 運算子會串連字串:The + operator concatenates strings:
string a = "good " + "morning";
這會建立包含 "good morning" 的字串物件。This creates a string object that contains "good morning".
字串是「不可變的」**;在建立物件之後,就無法變更字串物件的內容,雖然語法讓它看起來就像您可以這麼做一樣。Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this. 例如,當您撰寫此程式碼時,編譯器實際上會建立新的字串物件,以保存新序列的字元,並且會將新物件指派給 b
。For example, when you write this code, the compiler actually creates a new string object to hold the new sequence of characters, and that new object is assigned to b
. 已配置給 b
的記憶體 (當其包含字串 "h" 時) 即適用於記憶體回收。The memory that had been allocated for b
(when it contained the string "h") is then eligible for garbage collection.
string b = "h";
b += "ello";
[]
運算子可用於唯讀存取字串的個別字元。The []
operator can be used for readonly access to individual characters of a string. 有效的索引值從開始 0
,而且必須小於字串的長度:Valid index values start at 0
and must be less than the length of the string:
string str = "test";
char x = str[2]; // x = 's';
以類似的方式, []
運算子也可以用來逐一查看字串中的每個字元:In similar fashion, the []
operator can also be used for iterating over each character in a string:
string str = "test";
for (int i = 0; i < str.Length; i++)
{
Console.Write(str[i] + " ");
}
// Output: t e s t
字串常值的型別是 string
,可以撰寫為兩種形式:quoted 和 @
-quoted。String literals are of type string
and can be written in two forms, quoted and @
-quoted. 以引號括住的字串常值是以雙引號 (") 括住:Quoted string literals are enclosed in double quotation marks ("):
"good morning" // a string literal
字串常值可以包含任何字元常值。String literals can contain any character literal. 包含逸出序列。Escape sequences are included. 下列範例使用逸出序列 \\
表示反斜線、\u0066
表示字母 f,而 \n
表示新行字元。The following example uses escape sequence \\
for backslash, \u0066
for the letter f, and \n
for newline.
string a = "\\\u0066\n F";
Console.WriteLine(a);
// Output:
// \f
// F
注意
逸出代碼 \udddd
(其中 dddd
是四位數字) 代表 Unicode 字元 U+dddd
。The escape code \udddd
(where dddd
is a four-digit number) represents the Unicode character U+dddd
. 也會辨識八位數 Unicode 逸出代碼︰\Udddddddd
。Eight-digit Unicode escape codes are also recognized: \Udddddddd
.
逐字字串常值的開頭為 @
,也會用雙引號括住。Verbatim string literals start with @
and are also enclosed in double quotation marks. 例如:For example:
@"good morning" // a string literal
逐字字串的優點是「不會」** 處理逸出序列,例如,這可讓您輕鬆地撰寫完整 Windows 檔案名稱︰The advantage of verbatim strings is that escape sequences are not processed, which makes it easy to write, for example, a fully qualified Windows file name:
@"c:\Docs\Source\a.txt" // rather than "c:\\Docs\\Source\\a.txt"
若要在 @-quoted 字串中包含雙引號,請使用兩個雙引號︰To include a double quotation mark in an @-quoted string, double it:
@"""Ahoy!"" cried the captain." // "Ahoy!" cried the captain.
委派型別The delegate type
委派類型的宣告類似方法簽章。The declaration of a delegate type is similar to a method signature. 它具有傳回值以及任意類型之任何數目的參數:It has a return value and any number of parameters of any type:
public delegate void MessageDelegate(string message);
public delegate int AnotherDelegate(MyType m, long num);
在 .NET 中,System.Action
和 System.Func
型別提供許多常見委派的泛型定義。In .NET, System.Action
and System.Func
types provide generic definitions for many common delegates. 您多半不需要定義新的自訂委派型別。You likely don't need to define new custom delegate types. 反之,您可以建立所提供之泛型型別的具現化。Instead, you can create instantiations of the provided generic types.
delegate
是可用來封裝具名或匿名方法的參考型別。A delegate
is a reference type that can be used to encapsulate a named or an anonymous method. 委派類似 C++ 中的函式指標,但委派是型別安全而且安全的。Delegates are similar to function pointers in C++; however, delegates are type-safe and secure. 如需委派的應用程式,請參閱委派和泛型委派。For applications of delegates, see Delegates and Generic Delegates. 委派是事件的基礎。Delegates are the basis for Events. 委派的具現化方式是將它與具名或匿名方法建立關聯。A delegate can be instantiated by associating it either with a named or anonymous method.
委派必須使用具有相容傳回型別和輸入參數的方法或 Lambda 運算式進行具現化。The delegate must be instantiated with a method or lambda expression that has a compatible return type and input parameters. 如需方法簽章中所允許變異程度的詳細資訊,請參閱 Variance in Delegates (委派中的變異數)。For more information on the degree of variance that is allowed in the method signature, see Variance in Delegates. 若與匿名方法搭配使用,則會一起宣告要與它建立關聯的委派和程式碼。For use with anonymous methods, the delegate and the code to be associated with it are declared together.
動態型別The dynamic type
dynamic
型別指出使用變數和對其成員的參考,會略過編譯時間型別檢查。The dynamic
type indicates that use of the variable and references to its members bypass compile-time type checking. 相反地,這些作業會在執行階段解決。Instead, these operations are resolved at run time. dynamic
類型會簡化 Office Automation API 這類 COM API 的存取、IronPython 程式庫這類動態 API 的存取,以及 HTML 文件物件模型 (DOM) 的存取。The dynamic
type simplifies access to COM APIs such as the Office Automation APIs, to dynamic APIs such as IronPython libraries, and to the HTML Document Object Model (DOM).
在大多數情況下,dynamic
類型的行為與 object
類型類似。Type dynamic
behaves like type object
in most circumstances. 特別是,任何非 Null 運算式都可轉換成 dynamic
型別。In particular, any non-null expression can be converted to the dynamic
type. dynamic
型別與 object
的不同之處在於,包含型別 dynamic
運算式的操作,不會由編譯器解析或進行型別檢查。The dynamic
type differs from object
in that operations that contain expressions of type dynamic
are not resolved or type checked by the compiler. 編譯器會將作業資訊封裝在一起,而且稍後在執行階段會使用這項資訊來評估作業。The compiler packages together information about the operation, and that information is later used to evaluate the operation at run time. 在此程序期間,會將 dynamic
類型的變數編譯為 object
類型的變數。As part of the process, variables of type dynamic
are compiled into variables of type object
. 因此,dynamic
類型只存在於編譯時期,而非執行階段。Therefore, type dynamic
exists only at compile time, not at run time.
下列範例會對照 dynamic
類型的變數與 object
類型的變數。The following example contrasts a variable of type dynamic
to a variable of type object
. 若要在編譯時期驗證每個變數的類型,請將滑鼠指標放在 WriteLine
陳述式中的 dyn
或 obj
上方。To verify the type of each variable at compile time, place the mouse pointer over dyn
or obj
in the WriteLine
statements. 將下列程式碼複製到可使用 IntelliSense 的編輯器。Copy the following code into an editor where IntelliSense is available. IntelliSense 會顯示「動態」**** 來表示 dyn
,並顯示「物件」**** 來表示 obj
。IntelliSense shows dynamic for dyn
and object for obj
.
class Program
{
static void Main(string[] args)
{
dynamic dyn = 1;
object obj = 1;
// Rest the mouse pointer over dyn and obj to see their
// types at compile time.
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}
WriteLine 陳述式會顯示執行階段類型 dyn
和 obj
。The WriteLine statements display the run-time types of dyn
and obj
. 此時,兩者都有相同的類型:整數。At that point, both have the same type, integer. 此時會產生下列輸出:The following output is produced:
System.Int32
System.Int32
若要查看 dyn
與 obj
在編譯時期的差異,請在上述範例的宣告與 WriteLine
陳述式之間新增下列兩行。To see the difference between dyn
and obj
at compile time, add the following two lines between the declarations and the WriteLine
statements in the previous example.
dyn = dyn + 3;
obj = obj + 3;
嘗試新增運算式 obj + 3
中的整數和物件時報告編譯器錯誤。A compiler error is reported for the attempted addition of an integer and an object in expression obj + 3
. 不過,不會回報 dyn + 3
的錯誤。However, no error is reported for dyn + 3
. 在編譯時期不會檢查包含 dyn
的運算式,因為 dyn
的類型是 dynamic
。The expression that contains dyn
is not checked at compile time because the type of dyn
is dynamic
.
下列範例會在數個宣告中使用 dynamic
。The following example uses dynamic
in several declarations. Main
方法也會對照編譯時期類型檢查與執行階段類型檢查。The Main
method also contrasts compile-time type checking with run-time type checking.
using System;
namespace DynamicExamples
{
class Program
{
static void Main(string[] args)
{
ExampleClass ec = new ExampleClass();
Console.WriteLine(ec.exampleMethod(10));
Console.WriteLine(ec.exampleMethod("value"));
// The following line causes a compiler error because exampleMethod
// takes only one argument.
//Console.WriteLine(ec.exampleMethod(10, 4));
dynamic dynamic_ec = new ExampleClass();
Console.WriteLine(dynamic_ec.exampleMethod(10));
// Because dynamic_ec is dynamic, the following call to exampleMethod
// with two arguments does not produce an error at compile time.
// However, it does cause a run-time error.
//Console.WriteLine(dynamic_ec.exampleMethod(10, 4));
}
}
class ExampleClass
{
static dynamic field;
dynamic prop { get; set; }
public dynamic exampleMethod(dynamic d)
{
dynamic local = "Local variable";
int two = 2;
if (d is int)
{
return local;
}
else
{
return two;
}
}
}
}
// Results:
// Local variable
// 2
// Local variable
另請參閱See also
- C # 參考C# Reference
- C # 關鍵字C# Keywords
- 事件Events
- 使用動態類型Using Type dynamic
- 使用字串的最佳作法Best Practices for Using Strings
- 基底字元串作業Basic String Operations
- 建立新字串Creating New Strings
- 型別測試和轉換運算子Type-testing and cast operators
- 如何使用模式比對、as 和 as 運算子,安全地進行轉換How to safely cast using pattern matching and the as and is operators
- 逐步解說:建立和使用動態物件Walkthrough: creating and using dynamic objects
- System.Object
- System.String
- System.Dynamic.DynamicObject