2016-04-08 44 views
1

在C#和VB.Net我可以使用CallerMemberNameAttribute得到調用以字符串形式的名稱:C++/CLI:如何在C++/CLI中使用CallerMemberNameAttribute?

public void Caller([CallerMemberName]string memberName = "") 
{ 
    Debug.Print(memberName); 
} 

我願做同樣的在C++/CLI,但不知何故,我不能讓它加工。嘗試了幾個結構,我開始懷疑C++/CLI編譯器是否支持這個屬性。

這裏是一個(簡化的)實現:

using namespace System::Runtime::CompilerServices; 
public ref class InvokeExample 
{ 
    Invoke([CallerMemberName][Optional]String^ name) 
    { 
     Debug::Print(name); 
    } 
} 

當調用在C#應用這個方法名的值爲空。還嘗試使用屬性DefaultParameterValue但它也沒有幫助。現在用完了想法。

明顯的答案是,爲什麼不在C#中實現? 那麼,在這個特定的情況下,我僅限於C++/CLI。

+0

沒有意義的嘗試,這不是在C++編譯器中實現的。 C++/CLI在2005年被凍結。你必須使用[StackTrace class](http://stackoverflow.com/a/2652591/17034)。 –

+0

請注意漢斯的建議意味着嚴重的表現懲罰。 –

回答

1

我用反射器來查看C++/CLI和C#/ VB.Net版本之間的差異,他們看起來完全一樣。

然後使用ILDASM,現在我想我知道它爲什麼不起作用(看完這個post後)。

這裏的IL代碼:

C++/CLI

.method public hidebysig instance string 
     Caller([opt] string methodName) cil managed 
{ 
    .param [1] 
    .custom instance void [System]System.Runtime.InteropServices.DefaultParameterValueAttribute::.ctor(object) = (01 00 0E 00 00 00) 
    .custom instance void [mscorlib]System.Runtime.CompilerServices.CallerMemberNameAttribute::.ctor() = (01 00 00 00) 
    // Code size  2 (0x2) 
    .maxstack 1 
    IL_0000: ldarg.1 
    IL_0001: ret 
} // end of method ClassCPP::Caller 

C#

.method public hidebysig instance string 
     Caller([opt] string methodName) cil managed 
{ 
    .param [1] = "" 
    .custom instance void [mscorlib]System.Runtime.CompilerServices.CallerMemberNameAttribute::.ctor() = (01 00 00 00) 
    // Code size  2 (0x2) 
    .maxstack 1 
    .locals init ([0] string CS$1$0000) 
    IL_0000: ldarg.1 
    IL_0001: ret 
} // end of method ClassCS::Caller 
從VB.Net

IL代碼從C#不同之處如下:

.param [1] = nullref 

我懷疑是因爲C++/CLI會發出DefaultParameterValue,而不是使用默認值初始化.param [1],C#編譯器不會將該值轉換爲調用方成員名稱。

如果MSDN頁面描述了C++/CLI項目的這種限制,那將會很方便。會爲我們節省很多時間。