一般類型系統Common Type System

一般型別系統定義如何在 Common Language Runtime 中宣告、使用和管理型別,同時也是執行階段支援跨語言整合中很重要的一部分。The common type system defines how types are declared, used, and managed in the common language runtime, and is also an important part of the runtime's support for cross-language integration. 一般型別系統可執行下列功能:The common type system performs the following functions:

  • 建立利於提供跨語言整合、型別安全 (Type Safety) 和高效能程式碼執行的架構。Establishes a framework that helps enable cross-language integration, type safety, and high-performance code execution.

  • 提供可支援多種程式語言完整實作 (Implementation) 的物件導向模型。Provides an object-oriented model that supports the complete implementation of many programming languages.

  • 定義語言必須遵守的規則,有助於確保以不同語言撰寫的物件可彼此互動。Defines rules that languages must follow, which helps ensure that objects written in different languages can interact with each other.

  • 提供包含應用程式開發時使用之原始資料型別 (例如 BooleanByteCharInt32UInt64) 的程式庫。Provides a library that contains the primitive data types (such as Boolean, Byte, Char, Int32, and UInt64) used in application development.

此主題包括下列章節:This topic contains the following sections:

.NET 中的類型Types in .NET

.NET 中的所有型別屬於實值型別或是參考型別。All types in .NET are either value types or reference types.

如果資料型別的物件是由物件的實際值來表示,那麼這個資料型別就是實值型別。Value types are data types whose objects are represented by the object's actual value. 如果將實值型別的執行個體指派給變數,該變數會取得這個值的全新複本。If an instance of a value type is assigned to a variable, that variable is given a fresh copy of the value.

如果資料型別的物件是由物件之實際值的參考 (類似於指標) 來表示,那麼這個資料型別就是參考型別。Reference types are data types whose objects are represented by a reference (similar to a pointer) to the object's actual value. 如果將參考型別指派給變數,該變數就會參考 (指向) 原始值。If a reference type is assigned to a variable, that variable references (points to) the original value. 不會進行複製。No copy is made.

.NET 中的一般型別系統支援下列五種型別:The common type system in .NET supports the following five categories of types:

類別Classes

類別是指可以直接衍生自其他類別且隱含衍生自 System.Object 的參考型別。A class is a reference type that can be derived directly from another class and that is derived implicitly from System.Object. 類別會定義物件 (類別的執行個體) 可以執行的作業 (方法、事件或屬性) 以及物件包含的資料 (欄位)。The class defines the operations that an object (which is an instance of the class) can perform (methods, events, or properties) and the data that the object contains (fields). 雖然類別通常包括定義和實作 (不同於介面,例如介面只包含定義而不含實作),但是類別可以有一個或多個不具實作的成員。Although a class generally includes both definition and implementation (unlike interfaces, for example, which contain only definition without implementation), it can have one or more members that have no implementation.

下表將說明類別可以具有的某些特性。The following table describes some of the characteristics that a class may have. 每一個支援執行階段的語言都會提供一種方式,指出類別或類別成員具有這些其中一個或多個特性。Each language that supports the runtime provides a way to indicate that a class or class member has one or more of these characteristics. 然而,以 .NET 為目標的程式設計語言則無法使用所有這些特性。However, individual programming languages that target .NET may not make all these characteristics available.

特性Characteristic 描述Description
sealedsealed 指定無法從這個型別衍生出其他類別。Specifies that another class cannot be derived from this type.
實作implements 指出類別會以提供介面成員實作的方式來使用一個或多個介面。Indicates that the class uses one or more interfaces by providing implementations of interface members.
abstractabstract 表示這個類別無法執行個體化。Indicates that the class cannot be instantiated. 若要使用這個特性,必須從它衍生出其他類別。To use it, you must derive another class from it.
繼承inherits 指出類別的執行個體可用於已指定基底類別 (Base Class) 的任何位置。Indicates that instances of the class can be used anywhere the base class is specified. 從基底類別繼承的衍生類別可以使用基底類別所提供的任何公用成員實作,或者衍生類別可以利用本身的實作來覆寫公用成員的實作。A derived class that inherits from a base class can use the implementation of any public members provided by the base class, or the derived class can override the implementation of the public members with its own implementation.
exported 或 not exportedexported or not exported 指出是否可在定義類別的組件中看見類別。Indicates whether a class is visible outside the assembly in which it is defined. 這項特性僅適用於最上層類別,並不適用於巢狀類別。This characteristic applies only to top-level classes and not to nested classes.

注意

類別也可以透過巢狀方式置於父類別或結構中。A class can also be nested in a parent class or structure. 巢狀類別也具有成員特性。Nested classes also have member characteristics. 如需詳細資訊,請參閱巢狀型別For more information, see Nested Types.

沒有實作的類別成員是抽象成員。Class members that have no implementation are abstract members. 有一個或多個抽象成員的類別本身就是抽象的;所以無法建立它的新執行個體。A class that has one or more abstract members is itself abstract; new instances of it cannot be created. 有些以執行階段為目標的語言即使沒有任何抽象的成員,也允許您將類別標記為抽象。Some languages that target the runtime let you mark a class as abstract even if none of its members are abstract. 當您需要封裝一組衍生類別在適當時可繼承或覆寫的基本功能時,可以使用抽象類別 (Abstract Class)。You can use an abstract class when you want to encapsulate a basic set of functionality that derived classes can inherit or override when appropriate. 非抽象的類別即稱為實體類別 (Concrete Class)。Classes that are not abstract are referred to as concrete classes.

一個類別可以實作任意數量的介面,但是除了所有類別都會隱含繼承的來源 System.Object 以外,只能繼承一個基底類別。A class can implement any number of interfaces, but it can inherit from only one base class in addition to System.Object, from which all classes inherit implicitly. 所有類別都至少必須有一個建構函式,用來初始化類別的新執行個體。All classes must have at least one constructor, which initializes new instances of the class. 如果您沒有明確定義建構函式,大多數的編譯器會自動提供無參數建構函式。If you do not explicitly define a constructor, most compilers will automatically provide a parameterless constructor.

結構Structures

結構是自 System.ValueType (衍生自 System.Object) 隱含繼承的實質型別。A structure is a value type that derives implicitly from System.ValueType, which in turn is derived from System.Object. 在表示記憶體需求相當小的實質型別時,以及將值當做傳值參考傳遞給具有強型別參數的方法時,結構將相當實用。A structure is very useful for representing values whose memory requirements are small, and for passing values as by-value parameters to methods that have strongly typed parameters. 在 .NET 中,會將所有基本資料類型 (BooleanByteCharDateTimeDecimalDoubleInt16Int32Int64SByteSingleUInt16UInt32UInt64) 定義為結構。In .NET, all primitive data types (Boolean, Byte, Char, DateTime, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, and UInt64) are defined as structures.

與類別一樣,結構會定義資料 (結構的欄位) 以及可以在該資料上定義的作業 (結構的方法)。Like classes, structures define both data (the fields of the structure) and the operations that can be performed on that data (the methods of the structure). 這表示您可以在結構上呼叫方法,包括在 System.ObjectSystem.ValueType 類別上定義的虛擬方法,以及在實值型別本身定義的任何方法。This means that you can call methods on structures, including the virtual methods defined on the System.Object and System.ValueType classes, and any methods defined on the value type itself. 換言之,除了靜態與非靜態方法之外,結構還可以具有欄位、屬性和事件。In other words, structures can have fields, properties, and events, as well as static and nonstatic methods. 您可以建立結構的執行個體,將它們當做參數傳遞,並將它們當做區域變數儲存或將它們儲存到其他實值型別或參考型別的欄位中。You can create instances of structures, pass them as parameters, store them as local variables, or store them in a field of another value type or reference type. 結構也可以實作介面。Structures can also implement interfaces.

實值型別在許多層面上與類別不同。Value types also differ from classes in several respects. 首先,雖然它們隱含繼承自 System.ValueType,但是卻無法直接繼承自任何型別。First, although they implicitly inherit from System.ValueType, they cannot directly inherit from any type. 同樣地,所有實值型別都是密封型別,表示無法從中衍生其他型別。Similarly, all value types are sealed, which means that no other type can be derived from them. 實值型別不需要建構函式。They also do not require constructors.

對每一個實值型別而言,Common Language Runtime 都提供了對應的 Boxed 型別,這是具有與實值型別相同狀態和行為的類別。For each value type, the common language runtime supplies a corresponding boxed type, which is a class that has the same state and behavior as the value type. 實值型別的執行個體傳遞給接受型別為 System.Object 之參數的方法時,會進行 Boxed 處理。An instance of a value type is boxed when it is passed to a method that accepts a parameter of type System.Object. 當控制項從接受實質型別做為傳址參數的方法呼叫傳回時,它會 Unboxed (意即由類別的執行個體轉換回實質型別的執行個體)。It is unboxed (that is, converted from an instance of a class back to an instance of a value type) when control returns from a method call that accepts a value type as a by-reference parameter. 需要 Boxed 型別時,有些語言會要求您使用特殊的語法;其他語言則會在需要時自動使用 Boxed 型別。Some languages require that you use special syntax when the boxed type is required; others automatically use the boxed type when it is needed. 當您定義實值型別時,會同時定義 Boxed 和 Unboxed 型別。When you define a value type, you are defining both the boxed and the unboxed type.

列舉Enumerations

列舉 (Enum) 是直接繼承自 System.Enum 的實值型別,並且可以為基礎的基本型別數值提供替代名稱。An enumeration (enum) is a value type that inherits directly from System.Enum and that supplies alternate names for the values of an underlying primitive type. 列舉型別具有名稱、必須為內建帶正負號或不帶正負號之整數型別 (例如 ByteInt32UInt64) 的基礎型別,以及一組欄位。An enumeration type has a name, an underlying type that must be one of the built-in signed or unsigned integer types (such as Byte, Int32, or UInt64), and a set of fields. 欄位為靜態的常值欄位,每一個欄位各代表一個常數。The fields are static literal fields, each of which represents a constant. 相同的數值可指定給多個欄位。The same value can be assigned to multiple fields. 發生這種情況時,必須將其中一個數值標記為反映和字串轉換的主要列舉值。When this occurs, you must mark one of the values as the primary enumeration value for reflection and string conversion.

您可以將基礎型別的值指定給列舉型別,反之亦然 (Runtime 不需要轉型)。You can assign a value of the underlying type to an enumeration and vice versa (no cast is required by the runtime). 您可以建立列舉的執行個體,然後呼叫 System.Enum 的方法以及在列舉的基礎型別上定義的任何方法。You can create an instance of an enumeration and call the methods of System.Enum, as well as any methods defined on the enumeration's underlying type. 但是,在需要基礎型別的執行個體時,有些語言可能不允許您將列舉型別當成參數傳遞,反之亦然。However, some languages might not let you pass an enumeration as a parameter when an instance of the underlying type is required (or vice versa).

下列限制適用於列舉型別:The following additional restrictions apply to enumerations:

  • 不能定義自己的方法。They cannot define their own methods.

  • 不能實作介面。They cannot implement interfaces.

  • 不能定義屬性或事件。They cannot define properties or events.

  • 除非是巢狀置於泛型型別中,否則不能是泛型。They cannot be generic, unless they are generic only because they are nested within a generic type. 換句話說,列舉型別不能有自己的型別參數。That is, an enumeration cannot have type parameters of its own.

    注意

    使用 Visual Basic、C# 和 C++ 建立的巢狀型別 (包括列舉型別) 包含所有封入泛型型別的型別參數,因此,即使沒有自己的型別參數,仍舊是泛型型別。Nested types (including enumerations) created with Visual Basic, C#, and C++ include the type parameters of all enclosing generic types, and are therefore generic even if they do not have type parameters of their own. 如需詳細資訊,請參閱 Type.MakeGenericType 參考主題中的<巢狀型別>。For more information, see "Nested Types" in the Type.MakeGenericType reference topic.

FlagsAttribute 屬性代表一種特殊的列舉型別,稱為位元欄位 (Bit Field)。The FlagsAttribute attribute denotes a special kind of enumeration called a bit field. Runtime 本身無法區別傳統列舉型別和位元欄位,但是您所使用的語言或許可以區分出來。The runtime itself does not distinguish between traditional enumerations and bit fields, but your language might do so. 在區分時,可在位元欄位上使用位元 (Bitwise) 運算子來產生未命名的數值,但是不能用於列舉型別。When this distinction is made, bitwise operators can be used on bit fields, but not on enumerations, to generate unnamed values. 列舉型別通常用於唯一的項目 (Element) 清單,例如該星期的天數、國別或區域名稱等。Enumerations are generally used for lists of unique elements, such as days of the week, country or region names, and so on. 位元欄位通常用於可能以組合形式出現的特性或數量清單,例如 Red And Big And FastBit fields are generally used for lists of qualities or quantities that might occur in combination, such as Red And Big And Fast.

下列範例顯示如何使用位元欄位和傳統列舉型別。The following example shows how to use both bit fields and traditional enumerations.

using System;
using System.Collections.Generic;

// A traditional enumeration of some root vegetables.
public enum SomeRootVegetables
{
    HorseRadish,
    Radish,
    Turnip
}

// A bit field or flag enumeration of harvesting seasons.
[Flags]
public enum Seasons
{
    None = 0,
    Summer = 1,
    Autumn = 2,
    Winter = 4,
    Spring = 8,
    All = Summer | Autumn | Winter | Spring
}

public class Example
{
   public static void Main()
   {
       // Hash table of when vegetables are available.
       Dictionary<SomeRootVegetables, Seasons> AvailableIn = new Dictionary<SomeRootVegetables, Seasons>();

       AvailableIn[SomeRootVegetables.HorseRadish] = Seasons.All;
       AvailableIn[SomeRootVegetables.Radish] = Seasons.Spring;
       AvailableIn[SomeRootVegetables.Turnip] = Seasons.Spring | 
            Seasons.Autumn;

       // Array of the seasons, using the enumeration.
       Seasons[] theSeasons = new Seasons[] { Seasons.Summer, Seasons.Autumn, 
            Seasons.Winter, Seasons.Spring };

       // Print information of what vegetables are available each season.
       foreach (Seasons season in theSeasons)
       {
          Console.Write(String.Format(
              "The following root vegetables are harvested in {0}:\n", 
              season.ToString("G")));
          foreach (KeyValuePair<SomeRootVegetables, Seasons> item in AvailableIn)
          {
             // A bitwise comparison.
             if (((Seasons)item.Value & season) > 0)
                 Console.Write(String.Format("  {0:G}\n", 
                      (SomeRootVegetables)item.Key));
          }
       }
   }
}
// The example displays the following output:
//    The following root vegetables are harvested in Summer:
//      HorseRadish
//    The following root vegetables are harvested in Autumn:
//      Turnip
//      HorseRadish
//    The following root vegetables are harvested in Winter:
//      HorseRadish
//    The following root vegetables are harvested in Spring:
//      Turnip
//      Radish
//      HorseRadish
Imports System.Collections.Generic

' A traditional enumeration of some root vegetables.
Public Enum SomeRootVegetables
   HorseRadish
   Radish
   Turnip
End Enum 

' A bit field or flag enumeration of harvesting seasons.
<Flags()> Public Enum Seasons
   None = 0
   Summer = 1
   Autumn = 2
   Winter = 4
   Spring = 8
   All = Summer Or Autumn Or Winter Or Spring
End Enum 

' Entry point.
Public Class Example
   Public Shared Sub Main()
      ' Hash table of when vegetables are available.
      Dim AvailableIn As New Dictionary(Of SomeRootVegetables, Seasons)()
        
      AvailableIn(SomeRootVegetables.HorseRadish) = Seasons.All
      AvailableIn(SomeRootVegetables.Radish) = Seasons.Spring
      AvailableIn(SomeRootVegetables.Turnip) = Seasons.Spring Or _
                                               Seasons.Autumn
        
      ' Array of the seasons, using the enumeration.
      Dim theSeasons() As Seasons = {Seasons.Summer, Seasons.Autumn, _
                                     Seasons.Winter, Seasons.Spring}
        
      ' Print information of what vegetables are available each season.
      For Each season As Seasons In theSeasons
         Console.WriteLine(String.Format( _
              "The following root vegetables are harvested in {0}:", _
              season.ToString("G")))
         For Each item As KeyValuePair(Of SomeRootVegetables, Seasons) In AvailableIn
            ' A bitwise comparison.
            If(CType(item.Value, Seasons) And season) > 0 Then
               Console.WriteLine("  " + _
                     CType(item.Key, SomeRootVegetables).ToString("G"))
            End If
         Next
      Next
   End Sub 
End Class 
' The example displays the following output:
'    The following root vegetables are harvested in Summer:
'      HorseRadish
'    The following root vegetables are harvested in Autumn:
'      Turnip
'      HorseRadish
'    The following root vegetables are harvested in Winter:
'      HorseRadish
'    The following root vegetables are harvested in Spring:
'      Turnip
'      Radish
'      HorseRadish

介面Interfaces

介面會定義指定「可以執行」關聯性 (Relationship) 或「擁有」關聯性的合約。An interface defines a contract that specifies a "can do" relationship or a "has a" relationship. 介面常用來實作功能,例如比較和排序 (IComparableIComparable<T> 介面)、測試是否相等 (IEquatable<T> 介面),或列舉集合中的項目 (IEnumerableIEnumerable<T> 介面)。Interfaces are often used to implement functionality, such as comparing and sorting (the IComparable and IComparable<T> interfaces), testing for equality (the IEquatable<T> interface), or enumerating items in a collection (the IEnumerable and IEnumerable<T> interfaces). 介面可以擁有屬性、方法和事件,這些都是抽象成員,也就是說,雖然介面會定義成員及其簽章,但每個介面成員的功能則是由實作介面的型別所定義。Interfaces can have properties, methods, and events, all of which are abstract members; that is, although the interface defines the members and their signatures, it leaves it to the type that implements the interface to define the functionality of each interface member. 這表示,實作介面的任何類別或結構都必須為介面中宣告的抽象成員提供定義。This means that any class or structure that implements an interface must supply definitions for the abstract members declared in the interface. 介面可能會要求任何實作類別或結構也必須實作一個或多個其他介面。An interface can require any implementing class or structure to also implement one or more other interfaces.

下列限制適用於介面:The following restrictions apply to interfaces:

  • 介面可宣告為任何存取範圍,但是介面成員必須全部具有公用存取範圍。An interface can be declared with any accessibility, but interface members must all have public accessibility.

  • 介面無法定義建構函式。Interfaces cannot define constructors.

  • 介面不能定義欄位。Interfaces cannot define fields.

  • 介面可以只定義執行個體成員,Interfaces can define only instance members. 不能定義靜態成員。They cannot define static members.

由於可以使用相同簽章宣告成員的介面不只一個,而且這些成員可以具有分開的實作,因此每一種語言都必須提供規則,將實作對應到需要成員的介面。Each language must provide rules for mapping an implementation to the interface that requires the member, because more than one interface can declare a member with the same signature, and these members can have separate implementations.

委派Delegates

委派是參考型別,用途與 C++ 中的函式指標類似。Delegates are reference types that serve a purpose similar to that of function pointers in C++. 委派是用於 .NET 中的事件處理常式和回呼函式。They are used for event handlers and callback functions in .NET. 不同於函式指標,委派更具安全性、可以驗證,而且是型別安全 (Type Safe) 的。Unlike function pointers, delegates are secure, verifiable, and type safe. 委派型別可以代表具有相容簽章的執行個體方法或靜態方法。A delegate type can represent any instance method or static method that has a compatible signature.

如果委派參數的型別比方法參數的型別更嚴格,則委派的參數與對應的方法參數相容,因為這樣可保證傳遞給委派的引數能夠安全地傳遞給方法。A parameter of a delegate is compatible with the corresponding parameter of a method if the type of the delegate parameter is more restrictive than the type of the method parameter, because this guarantees that an argument passed to the delegate can be passed safely to the method.

同樣的,如果方法的傳回型別比委派的傳回型別更具限制性,由於此保證方法傳回的值會安全地轉換為委派的傳回型別,委派的傳回型別就會相容於方法的傳回型別。Similarly, the return type of a delegate is compatible with the return type of a method if the return type of the method is more restrictive than the return type of the delegate, because this guarantees that the return value of the method can be cast safely to the return type of the delegate.

例如,具有 IEnumerable 型別參數和 Object 傳回型別的委派,即可代表具有 Object 型別參數和 IEnumerable 型別傳回值的方法。For example, a delegate that has a parameter of type IEnumerable and a return type of Object can represent a method that has a parameter of type Object and a return value of type IEnumerable. 如需詳細資訊和範例程式碼,請參閱 Delegate.CreateDelegate(Type, Object, MethodInfo)For more information and example code, see Delegate.CreateDelegate(Type, Object, MethodInfo).

委派會繫結到其所代表的方法。A delegate is said to be bound to the method it represents. 除了繫結到方法以外,委派還可以繫結到物件。In addition to being bound to the method, a delegate can be bound to an object. 物件表示方法的第一個參數,而且每一次叫用委派時,都會傳遞給方法。The object represents the first parameter of the method, and is passed to the method every time the delegate is invoked. 如果方法是執行個體方法,那麼繫結物件會傳遞做為隱含的 this 參數 (Visual Basic 中則為 Me);如果是靜態方法,物件會傳遞做為方法的第一個正式參數,而且委派簽章必須符合其餘參數。If the method is an instance method, the bound object is passed as the implicit this parameter (Me in Visual Basic); if the method is static, the object is passed as the first formal parameter of the method, and the delegate signature must match the remaining parameters. 如需詳細資訊和範例程式碼,請參閱 System.DelegateFor more information and example code, see System.Delegate.

所有的委派都繼承自 System.MulticastDelegate,該項則繼承自 System.DelegateAll delegates inherit from System.MulticastDelegate, which inherits from System.Delegate. C#、Visual Basic 和 C++ 語言並不允許從這些型別繼承,The C#, Visual Basic, and C++ languages do not allow inheritance from these types. 而是提供關鍵字以宣告委派。Instead, they provide keywords for declaring delegates.

由於委派繼承自 MulticastDelegate,所以委派會具有引動過程清單,這是委派所代表方法的清單,在叫用 (Invoke) 委派時就會執行這些方法。Because delegates inherit from MulticastDelegate, a delegate has an invocation list, which is a list of methods that the delegate represents and that are executed when the delegate is invoked. 清單中的所有方法都會接收到叫用委派時所提供的引數。All methods in the list receive the arguments supplied when the delegate is invoked.

注意

在引動過程清單中具有一個以上方法的委派,即使擁有傳回型別,其傳回值也不會具有定義。The return value is not defined for a delegate that has more than one method in its invocation list, even if the delegate has a return type.

在許多情況下,例如回呼方法中,委派只代表一個方法,而且您所需要採取的動作,就是建立委派然後再叫用委派。In many cases, such as with callback methods, a delegate represents only one method, and the only actions you have to take are creating the delegate and invoking it.

對於代表多個方法的委派,.NET 會提供 DelegateMulticastDelegate 委派類別的方法,來支援將方法加入至委派引動清單 (Delegate.Combine 方法)、移除方法 (Delegate.Remove 方法),以及取得引動清單 (Delegate.GetInvocationList 方法) 等諸如此類的作業。For delegates that represent multiple methods, .NET provides methods of the Delegate and MulticastDelegate delegate classes to support operations such as adding a method to a delegate's invocation list (the Delegate.Combine method), removing a method (the Delegate.Remove method), and getting the invocation list (the Delegate.GetInvocationList method).

注意

在 C#、C++ 和 Visual Basic 中,並不需要對事件處理常式委派使用這些方法,因為這些語言都提供加入和移除事件處理常式的語法。It is not necessary to use these methods for event-handler delegates in C#, C++, and Visual Basic, because these languages provide syntax for adding and removing event handlers.

類型定義Type Definitions

型別定義包括下列:A type definition includes the following:

  • 在型別上定義的任何屬性 (Attribute)Any attributes defined on the type.

  • 型別的存取範圍 (可視性)The type's accessibility (visibility).

  • 型別的名稱The type's name.

  • 型別的基底型別The type's base type.

  • 由型別實作的任何介面Any interfaces implemented by the type.

  • 型別中每一個成員的定義Definitions for each of the type's members.

屬性Attributes

屬性提供了其他的使用者定義中繼資料。Attributes provide additional user-defined metadata. 最常見的屬性用法是,用來將關於型別的其他資訊儲存在組件中,或者在設計階段或執行階段環境中修改型別成員的行為。Most commonly, they are used to store additional information about a type in its assembly, or to modify the behavior of a type member in either the design-time or run-time environment.

屬性本身都是繼承自 System.Attribute 的類別。Attributes are themselves classes that inherit from System.Attribute. 每一種支援使用屬性的語言都有自己的語法,用於將屬性套用至語言項目。Languages that support the use of attributes each have their own syntax for applying attributes to a language element. 屬性可以幾乎套用至所有語言項目,而可以套用屬性的特定項目是由套用到該屬性類別的 AttributeUsageAttribute 定義。Attributes can be applied to almost any language element; the specific elements to which an attribute can be applied are defined by the AttributeUsageAttribute that is applied to that attribute class.

型別存取範圍Type Accessibility

所有型別都具有修飾詞 (Modifier),負責控制其他型別的存取範圍。All types have a modifier that governs their accessibility from other types. 下表說明執行階段所支援的型別存取範圍。The following table describes the type accessibilities supported by the runtime.

協助工具選項Accessibility 描述Description
publicpublic 型別可供所有組件存取The type is accessible by all assemblies.
組件 (assembly)assembly 型別只能在本身的組件中存取The type is accessible only from within its assembly.

巢狀型別的存取範圍是依據其存取範圍定義域,由成員的宣告存取範圍和立即包含型別的存取範圍定義域來決定。The accessibility of a nested type depends on its accessibility domain, which is determined by both the declared accessibility of the member and the accessibility domain of the immediately containing type. 但是,巢狀型別的存取範圍領域不能超過包含型別 (Containing Type) 的存取範圍領域。However, the accessibility domain of a nested type cannot exceed that of the containing type.

在程式 M 的型別 T 中宣告的巢狀成員 P,它的存取範圍領域定義如下 (請注意,M 本身也可能是型別):The accessibility domain of a nested member M declared in a type T within a program P is defined as follows (noting that M might itself be a type):

  • 如果 M 的宣告存取範圍是 publicM 的存取範圍領域就是 T 的存取範圍領域。If the declared accessibility of M is public, the accessibility domain of M is the accessibility domain of T.

  • 如果 M 的宣告存取範圍是 protected internalM 的存取範圍領域是 T 的存取範圍領域與 P 的程式文字和從 T 以外宣告的 P 所衍生任何型別的程式文字的交集。If the declared accessibility of M is protected internal, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of P and the program text of any type derived from T declared outside P.

  • 如果 M 的宣告存取範圍是 protectedM 的存取範圍領域是 T 的存取範圍領域與 T 的程式文字和 T 所衍生之任一型別的交集。If the declared accessibility of M is protected, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of T and any type derived from T.

  • 如果 M 的宣告存取範圍是 internalM 的存取範圍領域是 T 的存取範圍領域與 P 的程式文字的交集。If the declared accessibility of M is internal, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of P.

  • 如果 M 的宣告存取範圍是 privateM 的存取範圍領域就是 T 的程式文字。If the declared accessibility of M is private, the accessibility domain of M is the program text of T.

類型名稱Type Names

一般型別系統對於名稱只有兩項限制:The common type system imposes only two restrictions on names:

  • 所有名稱都是以 Unicode (16 位元) 字元字串的方式編碼。All names are encoded as strings of Unicode (16-bit) characters.

  • 名稱的內嵌 (16 位元) 值不允許為 0x0000。Names are not permitted to have an embedded (16-bit) value of 0x0000.

然而,大部分語言會對型別名稱強制執行其他限制。However, most languages impose additional restrictions on type names. 所有比較都是以位元組為基礎,因此會區分大小寫,而且與地區設定無關 (Locale-Independent)。All comparisons are done on a byte-by-byte basis, and are therefore case-sensitive and locale-independent.

雖然型別可能會參考其他模組和組件中的型別,但是型別必須在一個 .NET 模組中完整定義Although a type might reference types from other modules and assemblies, a type must be fully defined within one .NET module. (不過根據編譯器的支援,它可以分割成多個原始程式碼檔)。只有在命名空間中的型別名稱才必須是唯一的。(Depending on compiler support, however, it can be divided into multiple source code files.) Type names need be unique only within a namespace. 若要能完整辨認型別,必須以包含型別實作的命名空間來限定型別名稱。To fully identify a type, the type name must be qualified by the namespace that contains the implementation of the type.

基底型別和介面Base Types and Interfaces

型別可繼承其他型別的數值和行為。A type can inherit values and behaviors from another type. 一般型別系統不允許型別繼承一個以上的基底型別。The common type system does not allow types to inherit from more than one base type.

型別可實作任意數目的介面。A type can implement any number of interfaces. 若要實作介面,型別必須實作該介面的所有虛擬成員。To implement an interface, a type must implement all the virtual members of that interface. 虛擬方法可由衍生型別 (Derived Type) 實作,並且可以用靜態或動態方式叫用 (Invoke)。A virtual method can be implemented by a derived type and can be invoked either statically or dynamically.

型別成員Type Members

執行階段允許您定義能夠指定型別行為與狀態的型別成員。The runtime enables you to define members of your type, which specifies the behavior and state of a type. 型別成員包含下列:Type members include the following:

欄位Fields

欄位會描述並包含型別狀態組件。A field describes and contains part of the type's state. 欄位可為執行階段支援的任何型別。Fields can be of any type supported by the runtime. 最常見的情形是,欄位為 privateprotected,如此才能夠只在類別內部或從衍生類別存取這些欄位。Most commonly, fields are either private or protected, so that they are accessible only from within the class or from a derived class. 如果欄位的值可以本身型別以外進行修改,則通常會使用屬性集存取子。If the value of a field can be modified from outside its type, a property set accessor is typically used. 公開欄位通常是唯讀的,而且可以是下兩種型別:Publicly exposed fields are usually read-only and can be of two types:

  • 常數,它的值是在設計階段指派。Constants, whose value is assigned at design time. 雖然並不會使用 static (Visual Basic 中則為 Shared) 關鍵字定義,但是這些常數都是類別的靜態成員。These are static members of a class, although they are not defined using the static (Shared in Visual Basic) keyword.

  • 唯讀變數,其值可以在類別建構函式中進行指派。Read-only variables, whose values can be assigned in the class constructor.

下列範例說明兩種唯讀欄位的使用方法。The following example illustrates these two usages of read-only fields.

using System;

public class Constants
{
   public const double Pi = 3.1416;
   public readonly DateTime BirthDate;
   
   public Constants(DateTime birthDate)
   {
      this.BirthDate = birthDate;
   }
}

public class Example
{
   public static void Main()
   {
      Constants con = new Constants(new DateTime(1974, 8, 18));
      Console.Write(Constants.Pi + "\n");
      Console.Write(con.BirthDate.ToString("d") + "\n");
   }
}
// The example displays the following output if run on a system whose current
// culture is en-US:
//    3.1416
//    8/18/1974
Public Class Constants
   Public Const Pi As Double = 3.1416
   Public ReadOnly BirthDate As Date
   
   Public Sub New(birthDate As Date)
      Me.BirthDate = birthDate
   End Sub
End Class

Public Module Example
   Public Sub Main()
      Dim con As New Constants(#8/18/1974#)
      Console.WriteLine(Constants.Pi.ToString())
      Console.WriteLine(con.BirthDate.ToString("d"))
   End Sub
End Module
' The example displays the following output if run on a system whose current
' culture is en-US:
'    3.1416
'    8/18/1974

屬性Properties

屬性會為型別的值或狀態命名,並且定義用來取得或設定屬性值的方法。A property names a value or state of the type and defines methods for getting or setting the property's value. 屬性可以是基本型別、基本型別的集合、使用者定義型別或使用者定義型別的集合。Properties can be primitive types, collections of primitive types, user-defined types, or collections of user-defined types. 屬性通常是用來保持型別的公用 (Public) 介面與型別的實際表示相互獨立。Properties are often used to keep the public interface of a type independent from the type's actual representation. 這可以讓屬性反映並不直接儲存於類別中的值 (例如,屬性傳回已計算的值時),或者在值指派給私用欄位之前先執行驗證。This enables properties to reflect values that are not directly stored in the class (for example, when a property returns a computed value) or to perform validation before values are assigned to private fields. 下列範例說明第二種模式。The following example illustrates the latter pattern.

using System;

public class Person
{
   private int m_Age;
   
   public int Age
   { 
      get { return m_Age; }
      set {
         if (value < 0 || value > 125)
         {
            throw new ArgumentOutOfRangeException("The value of the Age property must be between 0 and 125.");
         }
         else
         {
            m_Age = value;
         }         
      }
   }
}
Public Class Person
   Private m_Age As Integer
   
   Public Property Age As Integer
      Get
         Return m_Age
      End Get
      Set
         If value < 0 Or value > 125 Then
            Throw New ArgumentOutOfRangeException("The value of the Age property must be between 0 and 125.")
         Else
            m_Age = value
         End If
      End Set
   End Property
End Class

除了含有屬性本身之外,包含可讀取屬性之類型的 Microsoft Intermediate Language (MSIL) 也含有 get_propertyname 方法,而包含可寫入屬性之型別的 MSIL 則含有 set_propertyname 方法。In addition to including the property itself, the Microsoft intermediate language (MSIL) for a type that contains a readable property includes a get_propertyname method, and the MSIL for a type that contains a writable property includes a set_propertyname method.

方法Methods

方法會描述可以在類型上執行的作業。A method describes operations that are available on the type. 方法的簽章會指定所有參數和傳回值可使用的型別。A method's signature specifies the allowable types of all its parameters and of its return value.

雖然大部分方法都會針對方法呼叫定義所需的精確參數數目,但有些方法可支援數目不定的參數。Although most methods define the precise number of parameters required for method calls, some methods support a variable number of parameters. 這些方法最後一個宣告的參數是以 ParamArrayAttribute 屬性標記。The final declared parameter of these methods is marked with the ParamArrayAttribute attribute. 語言編譯器通常會提供關鍵字,例如 C# 中的 params 和 Visual Basic 中的 ParamArray,如此便不需要明確使用 ParamArrayAttributeLanguage compilers typically provide a keyword, such as params in C# and ParamArray in Visual Basic, that makes explicit use of ParamArrayAttribute unnecessary.

建構函式Constructors

建構函式是一種特殊方法,它會建立類別或結構的新執行個體。A constructor is a special kind of method that creates new instances of a class or structure. 與其他任何方法一樣,建構函式可以包含參數,不過建構函式沒有傳回值,換言之,它們傳回 voidLike any other method, a constructor can include parameters; however, constructors have no return value (that is, they return void).

如果類別的原始程式碼沒有明確定義建構函式,則編譯器會包含無參數建構函式。If the source code for a class does not explicitly define a constructor, the compiler includes a parameterless constructor. 不過,如果類別的原始程式碼只定義參數化建構函式,Visual Basic 和 C# 編譯器並不會產生無參數建構函式。However, if the source code for a class defines only parameterized constructors, the Visual Basic and C# compilers do not generate a parameterless constructor.

如果結構的原始程式碼已定義建構函式,它們必須是參數化建構函式;結構並無法定義無參數建構函式,而且編譯器不會產生結構或其他實值型別的無參數建構函式。If the source code for a structure defines constructors, they must be parameterized; a structure cannot define a parameterless constructor, and compilers do not generate parameterless constructors for structures or other value types. 所有實值型別都有隱含的無參數建構函式。All value types do have an implicit parameterless constructor. 這個建構函式是由 Common Language Runtime 實作,會將結構的所有欄位初始化為其預設值。This constructor is implemented by the common language runtime and initializes all fields of the structure to their default values.

EventsEvents

事件 (Event) 會定義可以回應的事件 (Incident),並且定義用於訂閱、取消訂閱和產生事件 (Event) 的方法。An event defines an incident that can be responded to, and defines methods for subscribing to, unsubscribing from, and raising the event. 事件通常是用來通知其他型別有狀態變更。Events are often used to inform other types of state changes. 如需詳細資訊,請參閱事件For more information, see Events.

巢狀類型Nested Types

巢狀型別是一種型別,它是某個其他型別的成員。A nested type is a type that is a member of some other type. 巢狀型別應該緊密地與其包含型別結合,且不能與一般用途的型別一樣實用。Nested types should be tightly coupled to their containing type and must not be useful as a general-purpose type. 當宣告的型別使用及建立巢狀型別的執行個體時,巢狀型別會很有用處,且不會在公用成員中公開此巢狀型別的使用。Nested types are useful when the declaring type uses and creates instances of the nested type, and use of the nested type is not exposed in public members.

巢狀型別對於一些開發人員來說可能會覺得混淆,所以除非有強制性的理由,否則不應該讓巢狀型別公開可見。Nested types are confusing to some developers and should not be publicly visible unless there is a compelling reason for visibility. 在設計完善的程式庫中,開發人員應極少使用巢狀型別來將物件執行個體化或宣告變數。In a well-designed library, developers should rarely have to use nested types to instantiate objects or declare variables.

型別成員的特性Characteristics of Type Members

一般型別系統允許型別成員具有各種特性,但是所使用的語言並不需要支援所有特性。The common type system allows type members to have a variety of characteristics; however, languages are not required to support all these characteristics. 下表將描述成員特性。The following table describes member characteristics.

特性Characteristic 適用於Can apply to 描述Description
abstractabstract 方法、屬性和事件Methods, properties, and events 型別不提供方法的實作。The type does not supply the method's implementation. 繼承或實作抽象方法的型別必須提供方法的實作。Types that inherit or implement abstract methods must supply an implementation for the method. 唯一的例外狀況 (Exception) 是當衍生型別本身也是抽象型別時。The only exception is when the derived type is itself an abstract type. 所有抽象方法都是虛擬的。All abstract methods are virtual.
private、family、assembly、family 和 assembly、family 或 assembly 或是 publicprivate, family, assembly, family and assembly, family or assembly, or public 全部All 定義成員的存取範圍:Defines the accessibility of the member:

privateprivate
只能在與成員相同的型別或巢狀型別中存取。Accessible only from within the same type as the member, or within a nested type.

familyfamily
可在與成員相同的型別和從它繼承而來的衍生型別中存取。Accessible from within the same type as the member, and from derived types that inherit from it.

組件assembly
只能在已定義型別的組件中存取。Accessible only in the assembly in which the type is defined.

family 和 assemblyfamily and assembly
只能從同時限定家族和組件存取的型別中存取。Accessible only from types that qualify for both family and assembly access.

family 或 assemblyfamily or assembly
只能從限定家族或組件之一存取的型別中存取。Accessible only from types that qualify for either family or assembly access.

publicpublic
可從任何型別中存取。Accessible from any type.
finalfinal 方法、屬性和事件Methods, properties, and events 在衍生型別中無法覆寫虛擬方法。The virtual method cannot be overridden in a derived type.
initialize-onlyinitialize-only 欄位Fields 只能初始化數值,在初始化之後即無法寫入。The value can only be initialized, and cannot be written after initialization.
執行個體instance 欄位、方法、屬性和事件Fields, methods, properties, and events 如果成員未標記為 static (C# 和 C++)、Shared (Visual Basic)、virtual (C# 和 C++) 或 Overridable (Visual Basic),則為執行個體成員 (沒有 instance 關鍵字)。If a member is not marked as static (C# and C++), Shared (Visual Basic), virtual (C# and C++), or Overridable (Visual Basic), it is an instance member (there is no instance keyword). 在記憶體中,這類成員的複本數與使用它的物件數一樣。There will be as many copies of such members in memory as there are objects that use it.
常值literal 欄位Fields 指定給欄位的數值是在編譯時間得知的內建實值型別的固定值。The value assigned to the field is a fixed value, known at compile time, of a built-in value type. 常值 (Literal) 欄位有時候也稱為常數。Literal fields are sometimes referred to as constants.
newslot 或 overridenewslot or override 全部All 定義成員與具有相同簽章的繼承成員之間的互動方式:Defines how the member interacts with inherited members that have the same signature:

newslotnewslot
隱藏具有相同簽章的繼承成員。Hides inherited members that have the same signature.

覆寫override
取代繼承虛擬方法的定義。Replaces the definition of an inherited virtual method.

預設值為 newslot。The default is newslot.
靜態static 欄位、方法、屬性和事件Fields, methods, properties, and events 成員屬於定義於其上的型別,而非屬於特定的型別執行個體;即使沒有建立型別執行個體,成員仍然存在,而且供型別的所有執行個體共用。The member belongs to the type it is defined on, not to a particular instance of the type; the member exists even if an instance of the type is not created, and it is shared among all instances of the type.
虛擬virtual 方法、屬性和事件Methods, properties, and events 方法可由衍生型別實作,而且可以用靜態或動態方式叫用。The method can be implemented by a derived type and can be invoked either statically or dynamically. 如果使用動態引動,在執行時期進行呼叫的執行個體型別會決定呼叫哪一個方法實作,而不是由編譯時間得知的型別決定。If dynamic invocation is used, the type of the instance that makes the call at run time (rather than the type known at compile time) determines which implementation of the method is called. 若要用靜態方式叫用虛擬方法,可能必須將變數轉型為使用方法所需版本的型別。To invoke a virtual method statically, the variable might have to be cast to a type that uses the desired version of the method.

多載化Overloading

每一個型別成員都具有唯一 (Unique) 的簽章。Each type member has a unique signature. 方法簽章包含方法名稱和參數清單 (方法引數的順序和型別)。Method signatures consist of the method name and a parameter list (the order and types of the method's arguments). 只要簽章不相同,就可以在型別中定義具有相同名稱的多個方法。Multiple methods with the same name can be defined within a type as long as their signatures differ. 定義兩個或多個具有相同名稱的方法時,就說這個方法是多載。When two or more methods with the same name are defined, the method is said to be overloaded. 例如在 System.Char 中,會多載 IsDigit 方法。For example, in System.Char, the IsDigit method is overloaded. 其中一個方法採用 CharOne method takes a Char. 另一個方法則採用 StringInt32The other method takes a String and an Int32.

注意

傳回型別並不會視為方法簽章的一部分。The return type is not considered part of a method's signature. 換言之,如果這些方法的差異只在於傳回型別,就不能多載這些方法。That is, methods cannot be overloaded if they differ only by return type.

繼承、覆寫和隱藏成員Inheriting, Overriding, and Hiding Members

衍生型別會繼承其基底型別的所有成員;也就是說,在衍生型別上會定義這些成員,並供衍生型別使用。A derived type inherits all members of its base type; that is, these members are defined on, and available to, the derived type. 繼承成員的行為或品質可用下列兩種方式來修改:The behavior or qualities of inherited members can be modified in two ways:

  • 衍生型別可用相同的簽章定義新的成員,如此便可隱藏繼承的成員。A derived type can hide an inherited member by defining a new member with the same signature. 您可以將原先為 public 的成員設為 private 成員,或是為標記為 final 的繼承方法定義新的行為。This might be done to make a previously public member private or to define new behavior for an inherited method that is marked as final.

  • 衍生型別可覆寫繼承的虛擬方法。A derived type can override an inherited virtual method. 覆寫方法會提供新的方法定義,叫用方法時將根據執行時期的實值型別,而非根據編譯時間得知的變數型別。The overriding method provides a new definition of the method that will be invoked based on the type of the value at run time rather than the type of the variable known at compile time. 只有當虛擬方法未標記為 final,而且新的方法至少可像虛擬方法一樣存取時,方法才可覆寫虛擬方法。A method can override a virtual method only if the virtual method is not marked as final and the new method is at least as accessible as the virtual method.

另請參閱See also