C# 10 新功能 -- 命名空間

C# 10 這一次對於命名空間有一些新加入的功能,這一篇來說明一下用法。

global using

第一個概念是命名空間的全域引入,這個功能在於某些命名空間可能是大部分甚至全部檔案都會使用,不需要像以前在每個檔案都引入,只需引入一次就可以。

語法非常簡單,就是在 using 之前加入一個 global 宣告即可,例如:

global using System.Reflection;

這沒有規定一定得放在哪個特定的檔案,可以隨便放置在任何一個 cs 檔案中。建議為了管理方便,可以集中放置在一個 cs 檔案裡。

implicit using

有了全域引入,更進一步的功能就是隱含引入命名空間,開啟這個功能的方法是在 csproj 文件加入以下設定:

<PropertyGroup>
    // .. 略
    <ImplicitUsings>enable</ImplicitUsings>
    // .. 略
  </PropertyGroup>

一旦開啟了這個設定 (預設是開啟),首先會根據專案型態自動隱含引入某些命名空間,可以參考文件庫的隱含 using 指示詞內容的說明;但你不想看也沒關係,因為這個設定會在你的專案裡自動產生一個 cs 檔案,看那個檔案的內容就知道哪些命名空間有被引入,這個檔案的位置在 專案目錄 \ obj \ Debug or Release (根據你的建置設定) \ [框架版本] \ [專案名稱].GlobalUsings.g.cs  。

除了預設的以外,你也可以加入其他的命名空間,一樣是放在 csproj 裡面:

 <ItemGroup>
   <Using Include="System.Reflection" />
 </ItemGroup>

以下是一個比較完整的範例,因為我特意把框架設定為 .NET 5.0,所以必須明確指定編譯器的版本為 10.0:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <LangVersion>10.0</LangVersion>
  </PropertyGroup>
  <ItemGroup>
    <Using Include="System.Reflection" />
  </ItemGroup>
</Project>

這是一個主控台專案,可以看到自動產生的檔案內容如下:

// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Reflection;
global using global::System.Threading;
global using global::System.Threading.Tasks;
file-scoped namespace

最後一個是檔案範圍的命名空間宣告,傳統上使用的是區塊式的命名空間宣告:

namespace NamespaceSample003
{
    public class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

這種宣告的方式允許在一個檔案裏面具備多個命名空間,但大部分的情況我們通常都是一個檔案只放一個命名空間 (甚至一個檔案只有一個型別在裡面,是吧?),基於這樣的情境,可以使用 file-scoped namespace,好處就是看起來會少一層區塊:

namespace NamespaceSample003;
public class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");
    }
}

命名空間的部分大致就是這三樣,大家可以善加利用。