.NET 教學課程Tour of .NET

.NET 是一般用途開發平台。.NET is a general purpose development platform. 它有數種重要功能,例如支援多種程式設計語言、非同步和並行程式設計模型,以及原生互通性,可支援跨多重平台的眾多案例。It has several key features, such as support for multiple programming languages, asynchronous and concurrent programming models, and native interoperability, which enable a wide range of scenarios across multiple platforms.

本文提供 .NET 某些重要功能的逐步導覽。This article offers a guided tour through some of the key features of the .NET. 請參閱 .NET 架構元件主題以了解 .NET 的架構片段,以及其用途。See the .NET Architectural Components topic to learn about the architectural pieces of .NET and what they're used for.

如何執行程式碼範例How to run the code samples

若要了解如何設定開發環境以執行程式碼範例,請參閱入門主題。To learn how to set up a development environment to run the code samples, see the Getting Started topic. 請從此頁面將程式碼複製並貼入您的環境中來執行它們。Copy and paste code samples from this page into your environment to execute them.

程式語言Programming languages

.NET 支援多種程式設計語言。.NET supports multiple programming languages. .NET 實作會實作通用語言基礎結構 (CLI),它的其中一個功能是指定與語言無關的執行階段和語言互通性。The .NET implementations implement the Common Language Infrastructure (CLI), which among other things specifies a language-independent runtime and language interoperability. 這表示您可以選擇任何 .NET 語言,在 .NET 上建置應用程式與服務。This means that you choose any .NET language to build apps and services on .NET.

Microsoft 積極地開發並支援三種 .NET 語言:C#、F# 與 Visual Basic (VB)。Microsoft actively develops and supports three .NET languages: C#, F#, and Visual Basic (VB).

  • C# 既簡單、強大、型別安全且為物件導向,同時保留 C 樣式語言的易讀性與簡潔性。C# is simple, powerful, type-safe, and object-oriented, while retaining the expressiveness and elegance of C-style languages. 熟悉 C 和類似語言的任何人在適應 C# 方面很少有問題。Anyone familiar with C and similar languages finds few problems in adapting to C#. 若要深入了解 C#,請參閱 C# 指南Check out the C# Guide to learn more about C#.

  • F# 是跨平台、功能優先的程式語言,也支援傳統物件導向和命令式程式設計。F# is a cross-platform, functional-first programming language that also supports traditional object-oriented and imperative programming. 若要深入了解 F#,請參閱 F# 指南Check out the F# Guide to learn more about F#.

  • Visual Basic 是容易學習的語言,您可以使用該語言建置 .NET 上所執行的各種應用程式。Visual Basic is an easy language to learn that you use to build a variety of apps that run on .NET. 在所有的 .NET 語言中,VB 的語法最接近一般人類語言,因此通常可讓新手更輕鬆地開發軟體。Among the .NET languages, the syntax of VB is the closest to ordinary human language, often making it easier for people new to software development.

自動記憶體管理Automatic memory management

.NET 使用記憶體回收 (GC) 為程式提供自動記憶體管理。.NET uses garbage collection (GC) to provide automatic memory management for programs. GC 採用延遲方法來管理記憶體,優先考慮應用程式輸送量,而不是立即收集記憶體。The GC operates on a lazy approach to memory management, preferring app throughput to the immediate collection of memory. 若要深入了解 .NET GC,請參閱記憶體回收 (GC) 的基本概念To learn more about the .NET GC, check out Fundamentals of garbage collection (GC).

下列兩行會配置記憶體:The following two lines both allocate memory:

var title = ".NET Primer";
var list = new List<string>();

沒有類似的關鍵字可取消配置記憶體,因為當記憶體回收行程透過其排程執行回收記憶體時,就會自動取消配置。There's no analogous keyword to de-allocate memory, as de-allocation happens automatically when the garbage collector reclaims the memory through its scheduled run.

記憶體回收行程是服務之一,可確保記憶體安全The garbage collector is one of the services that help ensure memory safety. 如果程式只存取已配置的記憶體,就是記憶體安全。A program is memory safe if it accesses only allocated memory. 例如,執行階段可確保應用程式不會存取陣列界限外已取消配置的記憶體。For instance, the runtime ensures that an app doesn't access unallocated memory beyond the bounds of an array.

在下列範例中,執行階段會擲回 InvalidIndexException 例外狀況來確保記憶體安全:In the following example, the runtime throws an InvalidIndexException exception to enforce memory safety:

int[] numbers = new int[42];
int number = numbers[42]; // Will throw an exception (indexes are 0-based)

使用 Unmanaged 資源Working with unmanaged resources

有一些物件會參考 Unmanaged 資源Some objects reference unmanaged resources. Unmanaged 資源是指 .NET 執行階段不會自動維護的資源。Unmanaged resources are resources that aren't automatically maintained by the .NET runtime. 例如檔案控制程式碼就是 Unmanaged 資源。For example, a file handle is an unmanaged resource. FileStream 物件是Managed 物件,但會 Unmanaged 檔案控制代碼。A FileStream object is a managed object, but it references a file handle, which is unmanaged. 當您完成使用 FileStream 時,您必須釋放檔案控制代碼。When you're done using the FileStream, you need to release the file handle.

在.NET 中,參考 Unmanaged 資源的物件會實作 IDisposable 介面。In .NET, objects that reference unmanaged resources implement the IDisposable interface. 當您完成使用此物件時,您可以呼叫物件的 Dispose() 方法來釋放任何 Unmanaged 資源。When you're done using the object, you call the object's Dispose() method, which is responsible for releasing any unmanaged resources. .NET 語言為這類物件提供了 using 語法,此語法十分方便,如下列範例所示:.NET languages provide a convenient using syntax for such objects, as shown in the following example:

using System.IO;

using (FileStream stream = GetFileStream(context))
    // Operations on the stream

using 區塊完成後,.NET 執行階段會自動呼叫 stream 物件的 Dispose() 方法來釋放檔案控制代碼。Once the using block completes, the .NET runtime automatically calls the stream object's Dispose() method, which releases the file handle. 如果例外狀況造成控制項離開區塊,執行階段也會執行此作業。The runtime also does this if an exception causes control to leave the block.

如需詳細資料,請參閱下列主題:For more details, see the following topics:

型別安全Type safety

物件是特定類型的執行個體。An object is an instance of a specific type. 指定物件所允許的唯一作業會是其類型所允許的作業。The only operations allowed for a given object are those of its type. Dog 類型可能會有 JumpWagTail 方法,但沒有 SumTotal 方法。A Dog type may have Jump and WagTail methods but not a SumTotal method. 程式只能呼叫屬於指定類型的方法。A program only calls the methods belonging to a given type. 所有其他呼叫會導致編譯時期錯誤,或執行階段例外狀況 (如果使用動態功能或 object)。All other calls result in either a compile-time error or a run-time exception (in case of using dynamic features or object).

.NET 語言是物件導向,具有基底和衍生類別的階層架構。.NET languages are object-oriented with hierarchies of base and derived classes. .NET 執行階段只允許符合物件階層架構的的物件轉換和呼叫。The .NET runtime only allows object casts and calls that align with the object hierarchy. 請記住,以任何 .NET 語言所定義的每種類型都是衍生自基底 Object 型別。Remember that every type defined in any .NET language derives from the base Object type.

Dog dog = AnimalShelter.AdoptDog(); // Returns a Dog type.
Pet pet = (Pet)dog; // Dog derives from Pet.
Car car = (Car)dog; // Will throw - no relationship between Car and Dog.
object temp = (object)dog; // Legal - a Dog is an object.

此外也會使用型別安全,藉由確保存取子關鍵字的精確度,來協助強制執行封裝。Type safety is also used to help enforce encapsulation by guaranteeing the fidelity of the accessor keywords. 存取子關鍵字是控制其他程式碼存取指定型別成員的成品。Accessor keywords are artifacts which control access to members of a given type by other code. 這些關鍵字通常會用於某種類型中用來管理其行為的各種資料。These are usually used for various kinds of data within a type that are used to manage its behavior.

private Dog _nextDogToBeAdopted = AnimalShelter.AdoptDog()

C#、VB 與 F# 支援本機「型別推斷」。C#, VB, and F# support local type inference. 型別推斷表示編譯器會從右邊的運算式推算左邊的運算式類型。Type inference means that the compiler deduces the type of the expression on the left-hand side from the expression on the right-hand side. 這並不會破壞或規避型別安全。This doesn't mean that the type safety is broken or avoided. 產生的類型確實具有強型別,其中包含其所指的所有項目。The resulting type does have a strong type with everything that implies. 上述範例中的 dog 已重寫並引入型別推斷,範例的其餘部分則保持不變:From the previous example, dog is rewritten to introduce type inference, and the remainder of the example is unchanged:

var dog = AnimalShelter.AdoptDog();
var pet = (Pet)dog;
Car car = (Car)dog; // will throw - no relationship between Car and Dog
object temp = (object)dog; // legal - a Dog is an object
car = (Car)temp; // will throw - the runtime isn't fooled
car.Accelerate() // the dog won't like this, nor will the program get this far

F# 提供比 C# 和 VB 中的方法區域型別推斷更進步的型別推斷功能。F# has even further type inference capabilities than the method-local type inference found in C# and VB. 如需詳細資訊,請參閱型別推斷To learn more, see Type Inference.

委派和 LambdaDelegates and lambdas

委派是以方法簽章表示。A delegate is represented by a method signature. 任何具有該簽章的方法都可以指派給委派,並在叫用委派時執行。Any method with that signature can be assigned to the delegate and is executed when the delegate is invoked.

委派與 C++ 函式指標類似,不同之處在於委派是型別安全。Delegates are like C++ function pointers except that they're type safe. 委派是 CLR 型別系統中一種已中斷連線的方法。They're a kind of disconnected method within the CLR type system. 一般方法是附加到類別,並且只能透過靜態或執行個體呼叫慣例來直接呼叫。Regular methods are attached to a class and are only directly callable through static or instance calling conventions.

在 .NET 中,委派常用於事件處理常式以定義非同步作業,並可用於 Lambda 運算式,這是 LINQ 的基石。In .NET, delegates are commonly used in event handlers, in defining asynchronous operations, and in lambda expressions, which are a cornerstone of LINQ. 深入了解委派和 Lambda 主題。Learn more in the Delegates and lambdas topic.


泛型可讓程式設計師在設計其類別時引入「型別參數」,如此即可讓用戶端程式碼 (類型的使用者) 指定正確類型來取代型別參數。Generics allow the programmer to introduce a type parameter when designing their classes that allows the client code (the users of the type) to specify the exact type to use in place of the type parameter.

新增泛型功能是為了協助程式設計師實作泛型資料結構。Generics were added to help programmers implement generic data structures. 在此功能之前,若要讓 List 等類型成為泛型,您必須使用 object 類型的項目。Before their arrival in order for a type such as the List type to be generic, it would have to work with elements that were of type object. 這樣做會有各種效能及語意問題,更別提可能會有難以解決的執行階段錯誤。This had various performance and semantic problems, along with possible subtle runtime errors. 後者最糟的情況是當資料結構同時包含整數與字串時,而且會在使用清單的成員時擲回 InvalidCastExceptionThe most notorious of the latter is when a data structure contains, for instance, both integers and strings, and an InvalidCastException is thrown on working with the list's members.

下列範例顯示使用 List<T> 類型執行個體的基本程式正在執行:The following sample shows a basic program running using an instance of List<T> types:

using System;
using System.Collections.Generic;

namespace GenericsSampleShort
    public static void Main(string[] args)
        // List<string> is the client way of specifying the actual type for the type parameter T
        List<string> listOfStrings = new List<string> { "First", "Second", "Third" };

        // listOfStrings can accept only strings, both on read and write.

        // Below will throw a compile-time error, since the type parameter
        // specifies this list as containing only strings.

如需詳細資訊,請參閱泛型型別 (泛型) 概觀主題。For more information, see the Generic types (Generics) overview topic.

非同步程式設計Async programming

非同步程式設計是 .NET 中的最高階概念,包括執行階段、架構程式庫和 .NET 語言建構的非同步支援。Async programming is a first-class concept within .NET with async support in the runtime, framework libraries, and .NET language constructs. 就內部而言,它們是以物件 (例如 Task) 為基礎,可利用作業系統盡可能有效率地執行 I/O 繫結工作。Internally, they're based on objects (such as Task), which take advantage of the operating system to perform I/O-bound jobs as efficiently as possible.

若要深入了解 .NET 非同步程式設計,請從非同步概觀主題開始。To learn more about async programming in .NET, start with the Async overview topic.

Language Integrated Query (LINQ)Language Integrated Query (LINQ)

LINQ 是一組強大的 C# 和 VB 功能,可讓您撰寫簡單的宣告式程式碼來操作資料。LINQ is a powerful set of features for C# and VB that allow you to write simple, declarative code for operating on data. 資料可以是許多形式 (例如記憶體內部物件、SQL 資料庫或 XML 文件),但您撰寫的 LINQ 程式碼在資料來源方面通常大同小異。The data can be in many forms (such as in-memory objects, a SQL database, or an XML document), but the LINQ code you write typically doesn't differ by data source.

若要深入了解及查看一些範例,請參閱 LINQ (Language Integrated Query) 主題。To learn more and see some samples, see the LINQ (Language Integrated Query) topic.

原生互通性Native interoperability

每個作業系統都包含提供系統服務的應用程式開發介面 (API)。Every operating system includes an application programming interface (API) that provides system services. .NET 提供幾種方式來呼叫這些 API。.NET provides several ways to call those APIs.

執行原生互通性的主要方式是透過「平台叫用」(簡稱 P/Invoke),這在 Linux 和 Windows 平台之間都受到支援。The main way to do native interoperability is via "platform invoke" or P/Invoke for short, which is supported across Linux and Windows platforms. 另一項僅適用於 Windows 的原生互通性做法稱為 "COM Interop",可用來處理 Managed 程式碼中的 COM 元件A Windows-only way of doing native interoperability is known as "COM interop," which is used to work with COM components in managed code. 它是以 P/Invoke 基礎結構為建置基礎,但運作方式稍有不同。It's built on top of the P/Invoke infrastructure, but it works in subtly different ways.

Mono (以及 Xamarin) 對 Java 和 Objective-C 的互通性支援大致上很類似;也就是說,它們使用相同的原則。Most of Mono's (and thus Xamarin's) interoperability support for Java and Objective-C are built similarly, that is, they use the same principles.

如需原生互通性的詳細資訊,請參閱原生互通性文章。For more information about native interoperability, see the Native interoperability article.

Unsafe 程式碼Unsafe code

CLR 可讓您根據語言支援透過 unsafe 程式碼存取原生記憶體及執行指標算術。Depending on language support, the CLR lets you access native memory and do pointer arithmetic via unsafe code. 特定演算法和系統互通性需要這些作業。These operations are needed for certain algorithms and system interoperability. Unsafe 程式碼雖然功能強大,但除非是必須與系統 API 互通,或必須實作最有效率的演算法,否則不建議使用。Although powerful, use of unsafe code is discouraged unless it's necessary to interop with system APIs or implement the most efficient algorithm. Unsafe 程式碼在不同的環境中執行時可能不盡相同,而且也會失去記憶體回收行程和型別安全的好處。Unsafe code may not execute the same way in different environments and also loses the benefits of a garbage collector and type safety. 建議您盡可能限制和集中使用 Unsafe 程式碼,並徹底測試該程式碼。It's recommended to confine and centralize unsafe code as much as possible and test that code thoroughly.

下列範例是 StringBuilder 類別的 ToString() 方法修改後的版本。The following example is a modified version of the ToString() method from the StringBuilder class. 它說明如何使用 unsafe 程式碼直接四處移動記憶體區塊,以有效率地實作演算法:It illustrates how using unsafe code can efficiently implement an algorithm by moving around chunks of memory directly:

public override String ToString()
    if (Length == 0)
        return String.Empty;

    string ret = string.FastAllocateString(Length);
    StringBuilder chunk = this;
        fixed (char* destinationPtr = ret)
                if (chunk.m_ChunkLength > 0)
                    // Copy these into local variables so that they are stable even in the presence of ----s (hackers might do this)
                    char[] sourceArray = chunk.m_ChunkChars;
                    int chunkOffset = chunk.m_ChunkOffset;
                    int chunkLength = chunk.m_ChunkLength;

                    // Check that we will not overrun our boundaries.
                    if ((uint)(chunkLength + chunkOffset) <= ret.Length && (uint)chunkLength <= (uint)sourceArray.Length)
                        fixed (char* sourcePtr = sourceArray)
                            string.wstrcpy(destinationPtr + chunkOffset, sourcePtr, chunkLength);
                        throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index"));
                chunk = chunk.m_ChunkPrevious;
            } while (chunk != null);
    return ret;

後續步驟Next steps

若您對 C# 功能的教學課程感興趣,請參閱 C# 教學課程If you're interested in a tour of C# features, check out Tour of C#.

若您對 F# 功能的教學課程感興趣,請參閱 F# 教學課程If you're interested in a tour of F# features, see Tour of F#.

若要開始撰寫自己的程式碼,請瀏覽使用者入門If you want to get started with writing code of your own, visit Getting Started.

若要了解重要的 .NET 元件,請參閱 .NET 架構元件To learn about important components of .NET, check out .NET Architectural Components.