C#中nameof的實(shí)現(xiàn)實(shí)例
在 C# 中,nameof 是一個(gè)上下文關(guān)鍵字(contextual keyword),用于在編譯時(shí)獲取 變量、類(lèi)型或成員的名稱(chēng),并以字符串形式返回。它的主要作用是避免硬編碼字符串,提高代碼的可維護(hù)性和健壯性,尤其是在需要引用標(biāo)識(shí)符名稱(chēng)的場(chǎng)景中(如異常處理、日志記錄、數(shù)據(jù)綁定等)。
基本用法
nameof 可以用于以下場(chǎng)景:
獲取變量名
string myVariable = "Hello"; string variableName = nameof(myVariable); // 返回 "myVariable"
獲取屬性名
public class MyClass { public string MyProperty { get; set; } } MyClass obj = new MyClass(); string propertyName = nameof(obj.MyProperty); // 返回 "MyProperty"獲取類(lèi)型名
string typeName = nameof(MyClass); // 返回 "MyClass"
獲取方法名
public void MyMethod() { string methodName = nameof(MyMethod); // 返回 "MyMethod" }獲取命名空間或泛型類(lèi)型的部分名稱(chēng)
Console.WriteLine(nameof(System.Collections.Generic)); // 輸出 "Generic" Console.WriteLine(nameof(List<int>)); // 輸出 "List" Console.WriteLine(nameof(List<int>.Count)); // 輸出 "Count"
典型應(yīng)用場(chǎng)景
1.異常處理
在參數(shù)校驗(yàn)時(shí),使用 nameof 可以明確指出問(wèn)題所在的參數(shù)或?qū)傩裕?/p>
public string UserName
{
get => _userName;
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("Name cannot be null or empty.", nameof(UserName));
}
_userName = value;
}
}- 如果
UserName被設(shè)置為空,拋出的異常會(huì)明確顯示"UserName"作為參數(shù)名。
2.日志記錄
在日志中記錄代碼元素的名稱(chēng),避免硬編碼字符串:
Console.WriteLine($"Initializing {nameof(Color)} enum"); // 輸出 "Initializing Color"3.數(shù)據(jù)綁定與模型驗(yàn)證
在 MVC 或數(shù)據(jù)綁定框架中,結(jié)合 nameof 生成驗(yàn)證消息:
public class UserModel
{
[Required(ErrorMessage = $"The {nameof(UserName)} field is required.")]
public string UserName { get; set; }
}- 如果
UserName被重命名,nameof會(huì)自動(dòng)更新,避免字符串錯(cuò)誤。
4.單元測(cè)試
在測(cè)試中明確標(biāo)識(shí)測(cè)試的目標(biāo)方法或?qū)傩裕?/p>
[TestMethod]
public void TestUserNameProperty()
{
var service = new UserService();
Assert.ThrowsException<ArgumentException>(() => service.UserName = "",
$"Setting {nameof(UserService.UserName)} to empty should throw.");
}與ToString()的區(qū)別
| 特性 | nameof | ToString() |
|---|---|---|
| 執(zhí)行時(shí)機(jī) | 編譯時(shí)(生成字符串常量) | 運(yùn)行時(shí)(調(diào)用方法) |
| 返回內(nèi)容 | 標(biāo)識(shí)符的名稱(chēng)(如變量、屬性名) | 對(duì)象的字符串表示(如值或自定義格式) |
| 示例 | nameof(myVariable) → "myVariable" | myVariable.ToString() → "Hello" |
枚舉的對(duì)比
enum Color { Red, Green, Blue }
Color myColor = Color.Green;
string a = nameof(myColor); // 返回 "myColor"(變量名)
string b = nameof(Color.Blue); // 返回 "Blue"(枚舉成員名)
string c = myColor.ToString(); // 返回 "Green"(枚舉值的名稱(chēng))注意事項(xiàng)
編譯時(shí)操作nameof 在編譯時(shí)求值,因此不會(huì)引入運(yùn)行時(shí)開(kāi)銷(xiāo)。
不支持局部變量
不能用于局部變量(如方法內(nèi)部定義的變量):
void MyMethod()
{
int x = 10;
string name = nameof(x); // ? 錯(cuò)誤:x 是局部變量
}忽略 @ 符號(hào)
如果標(biāo)識(shí)符以 @ 開(kāi)頭(如 @class),@ 會(huì)被忽略:
var @new = 5; Console.WriteLine(nameof(@new)); // 輸出 "new"
泛型類(lèi)型的限制nameof(T) 返回的是泛型參數(shù)名(如 "T"),而非實(shí)際類(lèi)型名。若需要實(shí)際類(lèi)型名,需結(jié)合反射:
public void GenericMethod<T>()
{
string typeName = nameof(T); // 返回 "T"
// 使用反射獲取實(shí)際類(lèi)型名:
Type actualType = typeof(T);
string actualTypeName = actualType.Name; // 如 "String"
}C# 11 的新特性
從 C# 11 開(kāi)始,nameof 可用于 方法參數(shù) 和 屬性:
[ParameterString(nameof(msg))]
public static void Method(string msg)
{
[ParameterString(nameof(T))]
void LocalFunction<T>(T param) { }
var lambda = ([ParameterString(nameof(aNumber))] int aNumber) => aNumber.ToString();
}總結(jié)
nameof 是 C# 中非常實(shí)用的工具,尤其在需要引用標(biāo)識(shí)符名稱(chēng)的場(chǎng)景中(如異常處理、日志記錄、數(shù)據(jù)綁定)。它的核心優(yōu)勢(shì)包括:
- 避免硬編碼字符串,減少錯(cuò)誤。
- 編譯時(shí)檢查,確保代碼健壯性。
- 提高可讀性和可維護(hù)性,特別是在重構(gòu)時(shí)自動(dòng)更新名稱(chēng)。
通過(guò)合理使用 nameof,可以編寫(xiě)出更清晰、更可靠的代碼。
到此這篇關(guān)于C#中nameof的實(shí)現(xiàn)實(shí)例的文章就介紹到這了,更多相關(guān)C# nameof內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于C#繼承的簡(jiǎn)單應(yīng)用代碼分析
在本篇文章里小編給大家整理了一篇關(guān)于C#繼承的簡(jiǎn)單應(yīng)用代碼分析內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2021-05-05
C#存儲(chǔ)相同鍵多個(gè)值的Dictionary實(shí)例詳解
在本篇文章里小編給大家整理的是關(guān)于C#存儲(chǔ)相同鍵多個(gè)值的Dictionary實(shí)例內(nèi)容,需要的朋友們可以學(xué)習(xí)下。2020-03-03
C#調(diào)用百度翻譯API實(shí)現(xiàn)一個(gè)翻譯功能
一直喜歡用Google Translate API進(jìn)行在線翻譯,但是服務(wù)越來(lái)越慢這篇文章,所以只能換一個(gè)了,主要給大家介紹了關(guān)于C#調(diào)用百度翻譯API實(shí)現(xiàn)一個(gè)翻譯功能的相關(guān)資料,需要的朋友可以參考下2021-06-06
詳解WPF如何顯示具有層級(jí)關(guān)系的數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了在WPF中如何顯示具有層級(jí)關(guān)系的數(shù)據(jù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
C#實(shí)現(xiàn)簡(jiǎn)單的Http請(qǐng)求實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)簡(jiǎn)單的Http請(qǐng)求的方法,以實(shí)例形式較為詳細(xì)的分析了C#實(shí)現(xiàn)Http請(qǐng)求的具體方法,需要的朋友可以參考下2015-01-01
C#利用Refit實(shí)現(xiàn)JWT自動(dòng)續(xù)期詳解
Refit?是一個(gè)受到Square的Retrofit庫(kù)(Java)啟發(fā)的自動(dòng)類(lèi)型安全REST庫(kù),這篇文章主要為大家介紹了C#如何利用Refit實(shí)現(xiàn)JWT自動(dòng)續(xù)期,感興趣的可以了解下2023-08-08
C#使用List類(lèi)實(shí)現(xiàn)動(dòng)態(tài)變長(zhǎng)數(shù)組的方法
這篇文章主要介紹了C#使用List類(lèi)實(shí)現(xiàn)動(dòng)態(tài)變長(zhǎng)數(shù)組的方法,涉及C#中List類(lèi)的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04

