簡體   English   中英

在C#中模擬C ++宏的正確方法是什么

[英]What's the proper way to emulate C++ macros in C#

我了解為什么宏不包含在語言中; 他們很容易受到虐待。 但是,我一次又一次地偶然發現它們似乎可取的情況。 就在最近,我正在編寫一種記錄圖像文件的方法:

public void LogImage(Bitmap image, string name)
{
    image.Save(LogRootDirectory + name + ".bmp");
}

隨后,我認為利用nameof()功能更好地提供有關我正在記錄的圖像的信息很聰明。 在我的代碼的幾個地方,我有幾行與此相似:

ImageLogger?.LogImage(processedImage, nameof(processedImage));

使我困擾的是此操作的重復性,我更希望使用類似於以下命令的預處理器命令:

#define LOGIMAGE(img) ImageLogger?.LogImage(img, nameof(img));

有沒有一種方法可以模仿上述宏行為,從而更好地簡化我的代碼?

注意: 這個問題的不同之處在於,作者詢問的是C#中是否存在按處理器定義。 我從一開始就明確指出我不知道它們的斷言。 我的問題是關於我可能會使用的替代技術。 我相信標記的答案是提供給我的。

如果您在C#中對編譯時的技巧不知所措,那么您只是在濫用表達式樹而已。

public void LogImage(Expression<Func<Bitmap>> b) {
    var memberExpression = b.Body as MemberExpression;
    if (memberExpression == null) throw new ArgumentException("Must be invoked with a member reference.");
    string name = memberExpression.Member.Name;
    Bitmap bitmap = b.Compile()();
    LogImage(bitmap, name);
}

調用為

ImageLogger?.LogImage(() => processedImage);

即使從未調用過LogImage ,在調用站點上生成表達式樹也有一些開銷,因此盡管這很聰明,但也不要過度使用。 另外,這要求您的位圖具有名稱( getMyProcessedImage()將不起作用),如果C#支持它們( nameof(getMyProcessedImage())無效),這恰恰也是您使用宏也會遇到的問題,除了直到運行時它才會引發異常。 因此,就安全性而言,它也不是那么熱門。

就個人而言,我只需再次輸入名稱即可。 我什nameof不使用nameof 用變量名記錄圖像對我來說似乎是一種可疑的做法。 如果我確實想明確引用源代碼中生成位圖的位置,則可以使用調用者信息:

public void LogImage(
    Bitmap b, 
    [CallerFilePath] string filePath = "", 
    [CallerLineNumber] int lineNumber = 0
) {
    LogImage(b, $"{Path.GetFileNameWithoutExtension(filePath)}({lineNumber})");
}

只需調用為

ImageLogger?.LogImage(processedImage);

當然,這確實假設您希望每個位置都有唯一的位圖,但是給定名稱“ logger”似乎是一個適當的假設。

您可以利用匿名類型將具有自動生成的屬性名稱這一事實。 首先定義一個重載,如:

public void LogImage(object obj)
{
    var prop = obj.GetType().GetProperties()[0];
    string name = prop.Name;
    Bitmap bitmap = (Bitmap)prop.GetValue(obj);
    LogImage(bitmap, name);
}

然后,當您要記錄圖像時,請使用匿名類型調用它:

ImageLogger?.LogImage(new { processedImage });

這是對機制的濫用,在生產代碼中,為了清楚起見,我可能傾向於兩次鍵入該名稱。 同樣,在許多情況下,這並不是完全有效的,但是在這里我們談論的是將圖像保存到文件中,因此分配小對象和反射的額外成本可以忽略不計。

暫無
暫無

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

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