簡體   English   中英

在C#中編譯時間反射

[英]Compile Time Reflection in C#

我經常編寫C#代碼,必須使用魔術字符串來表達屬性名稱。 每個人都知道魔術弦的問題。 它們很難重構,它們沒有編譯時檢查,並且通常會導致難以診斷的問題。 然而,C#/ .NET 在整個地方使用它們來表示屬性/類/方法名稱。

這個問題已持續多年和多年,目前唯一可行的解​​決方案是使用表達式樹,然后在運行時解析屬性名稱。 這使您獲得令人滿意的編譯時檢查,但它使代碼復雜化(需要Expression類型的參數), 並且會產生運行時成本。

有沒有人知道是否有一個特性考慮因為C#/ .NET添加編譯時反射來克服這個普遍存在的問題?

看起來這將是一個簡單的補充,它將是一個非破壞性的變化,它將使許多開發人員受益匪淺。 typeof()運算符已經執行了編譯時反射的形式,因此看起來運算符nameof()(或類似的東西)將非常互補。

此外,有沒有人知道這個功能的任何潛在問題?

謝謝您的幫助。

在C#6.0中,添加了一個新的運算符nameof ,它允許您在編譯時獲取屬性,類,字段,事件和變量的名稱。

鏈接到設計說明

不再反映編譯器在設計時已經知道的信息!

直接來源 - 這是C#語言設計師的博客文章,這篇文章中的“用戶”詢問與您相同的問題並得到解答。 作者說,需要為你想要求的每個元數據項指定一個語法,這不是一件容易的事 - 即。 你想要哪個超載,如果你想要“info-of”方法並且方法被重載了? 如果涉及泛型和顯式接口實現會怎樣? 等等。 事實證明,雖然由於這些原因在2009年被認為不值得實施,但我們將在2015年的C#6中獲得它 - 請參閱2014年7月9日的C#語言設計說明

我遇到了類似的問題。 最近才發現.NET Framework 4.5具有一個名為Caller Info屬性的功能。 通過使用這些,您可以在編譯時獲取有關調用方的信息。 您可以獲取源代碼的文件路徑,源代碼中的行號以及調用者的成員名稱。

public void DoProcessing()
{
    TraceMessage("Something happened.");
}

public void TraceMessage(string message,
        [CallerMemberName] string memberName = "",
        [CallerFilePath] string sourceFilePath = "",
        [CallerLineNumber] int sourceLineNumber = 0)
{
    Trace.WriteLine("message: " + message);
    Trace.WriteLine("member name: " + memberName);
    Trace.WriteLine("source file path: " + sourceFilePath);
    Trace.WriteLine("source line number: " + sourceLineNumber);
}

然而,C#/ .NET在整個地方使用它們來表示屬性/類/方法名稱。

首先:我不同意。 有一些框架(WebForms,例如)在整個地方使用魔術字符串,但C#和.NET的基礎庫往往會非常好地避免這種情況。

其次:在使用魔術字符串的許多情況下,ReSharper能夠識別錯誤。 這可以幫助很多。

最后:您可以通過Roslyn編譯器提出要求,該編譯器承諾提供“編譯即服務”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM