C# 程式設計人員參考 object 型別是.NET Framework 中,System.Object 的別名 您可以將 任何型別的值指派給 object 型別的變數 所有的資料型別, 包括預先定義的和使用者定義的, 都繼承自 System.Object 類別 object 資料型別是物件 Box 目標或來源的型 別 範例下列範例顯示 object 型別的變數如何接受任何資料型別的值, 以及 object 型別的變數可如何使用.NET Framework 內的方法以應用在 System.Object 上 // keyword_object.cs using System; public class MyClass1 { public int i = 10; public class MyClass2 { public static void Main() { object a; a = 1; // an example of boxing 2006/3/2 1
Console.WriteLine(a); Console.WriteLine(a.GetType()); Console.WriteLine(a.ToString()); Console.WriteLine(); a = new MyClass1 (); MyClass1 ref_myclass1; ref_myclass1 = (MyClass1)a; Console.WriteLine(ref_MyClass1.i); 輸出 1 System.Int32 1 10 2006/3/2 2
Boxing Boxing that an object is automatically created from a value (that is of some value type). So a value can be used in contexts where an object is expected. 範例 : ArrayList tarraylist=new ArrayList(); tarraylist.add(27); // 將 27 轉成 object 存入 tarraylist 中. 此為 Boxing The reverse process (called unboxing) is also possible: int tvalue = (int) tarraylist[0]; Automatic boxing and unboxing are not present in Java. Instead, in Java, you have to do these tasks explicitly using the wrapper types. // SamplesArrayList.cs using System; using System.Collections; public class SamplesArrayList { public static void Main() { // Creates and initializes a new ArrayList. ArrayList myal = new ArrayList(); myal.add("hello"); myal.add("world"); myal.add("!"); myal.add(3); // 先將 3 box 成 object, 再放進 List 中. 2006/3/2 3
// Displays the properties and values of the ArrayList. Console.WriteLine( "myal" ); Console.WriteLine( "\tcount: {0", myal.count ); Console.WriteLine( "\tcapacity: {0", myal.capacity ); Console.Write( "\tvalues:" ); PrintValues( myal ); public static void PrintValues( IEnumerable mylist ) { System.Collections.IEnumerator myenumerator = mylist.getenumerator(); while ( myenumerator.movenext() ) Console.Write( "\t{0", myenumerator.current ); Console.WriteLine(); /* This code produces the following output. myal Count: 4 Capacity: 16 Values: Hello World! 3 */ 2006/3/2 4
C# 語言規格 4.3.1 Box 轉換 Box 轉換允許數值型別隱含地轉換成參考型別 因此出現下列 Box 轉換 : 從任何數值型別 ( 包含任何列舉型別 ) 轉換成 object 型別 從任何數值型別 ( 包含任何列舉型別 ) 轉換成 System.ValueType 型別 從任何數值型別轉換成數值型別實作的任何介面型別 從任何列舉型別轉換成 System.Enum 型別 Boxing 一個數值型別的數值時, 會包含配置一個物件執行個體, 並將數值型別數值複製到該執行個體中 說明數值型別值的 Boxing 實際程序的好方法, 是想像該類型別有個 Boxing 類別 針對任何數值型別 T 而言,boxing 類別會表現它好像是由下列方式宣告一樣 : sealed class T_Box: System.ValueType { T value; public T_Box(T t) { value = t; 現在為型別 T 的 v 值進行 Boxing 會執行 new T_Box(v) 運算式, 並將產生的執行個體傳回當作 object 型別的值 因此, 下面這段陳述式 int i = 123; object box = i; 2006/3/2 5
應該會對應到 int i = 123; object box = new int_box(i); 上述 T_Box 和 int_box 之類的 Boxing 類別實際上並不存在, 而一個 Boxed 值的動態型別也並非真的是一個類別型別 相反地, 型別 T 的一個 Boxed 值會擁有動態型別 T, 而使用 is 運算子的動態型別檢查只會參考型別 T 例如, int i = 123; object box = i; if (box is int) { Console.Write("Box contains an int"); 將會在主控台上輸出 Box contains an int 字串 一個 Box 轉換表示將會為要 Boxed 的值建立複本 這點和將參考型別轉換成 object 型別是不同的, 在這當中, 數值會繼續參考相同的執行個體, 且只是當作較少衍生的 object 型別 例如, 給定下列宣告 struct Point{ public int x, y; public Point(int x, int y) { this.x = x; this.y = y; 下列陳述式 2006/3/2 6
Point p = new Point(10, 10); object box = p; p.x = 20; Console.Write(((Point)box).x); 將會在主控台上輸出值 10, 因為出現在 p 的設定以隱含 Boxing 運算到 box, 會產生要複製的 p 值 如果 Point 已宣告成 class, 輸出結果就是值 20, 是因為 p 和 box 會參考相同的執行個體 2006/3/2 7
Properties Besides constructors, fields and methods, in.net languages, a class type (or a struct type) may also declare properties. Properties should be used instead of providing get and set methods. In the following example, the class Point is providing a property called X: 範例 : public class Point { private int ix; private int iy; public Point(int px, int py){ ix = px; iy = py; public int X{ get { return ix; set { ix = value; public int Y{ get { return iy; set { iy = value; public class Test{ public static void Main(string [] args){ Point tpoint = new Point(100, 200); int tx = tpoint.x; // uses get tpoint.x = 150; // uses set tpoint.x++; // uses get and set 2006/3/2 8
Indexers and operator overloading In C#, a class type (or a struct type) may declare indexers and/or operators. In the same way that a property provides access to one value, an indexer provides access to an array of values. An operator declaration permits a class (or a struct) to define new meanings for existing operators (such as ==, <, +, ++). 2006/3/2 9