隨著 dotnet 6 開始,現在的 C# dotnet 可以使用頂級語句非常方便建立一個小型專案,包含的程式碼也特別少。本文將和大家介紹如何在頂級語句裡面定義屬性
如以下程式碼是傳統的控制檯應用程式的程式碼
using System;
namespace Application
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
可以看到即使是一個簡單的應用,也需要不少的程式碼。在 dotnet 6 開始,咱可以使用非常方便的頂級語句代替以上程式碼的功能,只需一句程式碼即可
Console.WriteLine("Hello World!");
詳細請看 頂級語句 - C# 教程 - C# - Microsoft Learn
然而有些時候,咱需要定義一些屬性用來輔助某些特定的業務,卻會發現在頂級語句裡面定義方法很簡單,但是定義屬性卻報錯
如以下程式碼將不能透過構建
Foo = "Hello, World!";
Console.WriteLine(Foo);
static string Foo { set; get; }
錯誤提示內容如下
error CS0116: 名稱空間不能直接包含欄位、方法或語句之類的成員
解決方法是寫一個名為 Program 的 partial 類,程式碼如下
partial class Program
{
}
在 Program 裡面定義屬性是非常正確的,修改之後的程式碼如下
Foo = "Hello, World!";
Console.WriteLine(Foo);
partial class Program
{
public static string Foo { set; get; }
}
以上程式碼是可以透過構建的。其根本原因是頂級語句只是一個語法層面的功能,構建之後的程式碼全部都會被放入到名為 Program 的型別的 Main 方法裡面
回顧一開始最簡短的如下一句程式碼的頂級語句
Console.WriteLine("Hello World!");
其構建出來的程式碼對應的低階 C# 大概如下
using System;
using System.Runtime.CompilerServices;
[CompilerGenerated]
internal class Program
{
private static void <Main>$(string[] args)
{
Console.WriteLine("Hello, World!");
}
public Program()
{
base..ctor();
}
}
如此可以看到實際上是生成了一個名為 Program 的型別。這時候再寫一個 partial 的 Program 就可以與生成的 Program 類合併
換句話說,如下程式碼也是完全可以構建透過的
var program = new Program();
Console.WriteLine("Hello, World!");
即不需要手動定義 Program 類,即可使用自動生成的 Program 型別
利用自動生成的 Program 類新增屬性,從而被頂級語句方便的訪問到,這就是在頂級語句裡面新增屬性的核心實現原理
Foo = "Hello, World!";
Console.WriteLine(Foo);
partial class Program
{
public static string Foo { set; get; }
}
以上程式碼的對應的低階 C# 程式碼大概如下
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
internal class Program
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private static string <Foo>k__BackingField;
private static void <Main>$(string[] args)
{
Program.Foo = "Hello, World!";
Console.WriteLine(Program.Foo);
}
public static string Foo
{
[CompilerGenerated]
set
{
Program.<Foo>k__BackingField = value;
}
[CompilerGenerated]
get
{
return Program.<Foo>k__BackingField;
}
}
public Program()
{
base..ctor();
}
}
由於頂級語句是將程式碼放入到名為 Program 類裡面,此時即可透過再寫一個 partial 的 Program 用來定義屬性,就可以在構建時自動被合入到生成的類裡面
可以看到寫到一個檔案裡面的 Foo 屬性在構建的時候被和頂級語句合併到一起,如此的程式碼可以做到看起來十分簡單,且不會丟失屬性的功能
額外說明一下的是這裡定義的屬性只能的靜態的,在頂級語句裡面,除非構建 Program 的例項,否則將無法直接訪問到屬性
如此即可實現在頂級語句裡面定義屬性
本文程式碼放在 github 和 gitee 上,可以使用如下命令列拉取程式碼。我整個程式碼倉庫比較龐大,使用以下命令列可以進行部分拉取,拉取速度比較快
先建立一個空資料夾,接著使用命令列 cd 命令進入此空資料夾,在命令列裡面輸入以下程式碼,即可獲取到本文的程式碼
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 082e98d35ef7f959057b76e1f70010651fa18713
以上使用的是國內的 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令列繼續輸入以下程式碼,將 gitee 源換成 github 源進行拉取程式碼。如果依然拉取不到程式碼,可以發郵件向我要程式碼
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 082e98d35ef7f959057b76e1f70010651fa18713
獲取程式碼之後,進入 Workbench/DawkuhelwhehairallweeFewewoyelfalar 資料夾,即可獲取到原始碼
更多技術部落格,請參閱 部落格導航