2016-04-08 5 views
1

В C# и VB.Net я могу использовать CallerMemberNameAttribute, чтобы получить имя запустившего в виде строки:C++/CLI: Как использовать CallerMemberNameAttribute в C++/CLI?

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] (http://stackoverflow.com/a/2652591/17034). –

+0

Имейте в виду, что предложение Ганса подразумевает серьезный штраф за исполнение. –

ответ

1

Я использовал отражатель для просмотра различий между C++/CLI и версией C#/VB.Net, и они выглядели точно так же.

Затем использовался ILDASM, и теперь я думаю, что знаю, почему он не работает (после прочтения этого post).

Вот код иль:

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 

IL код из VB.Net отличается от C# следующим образом:

.param [1] = nullref 

Я подозреваю, что, поскольку C++/CLI испускает DefaultParameterValue вместо инициализации .param [1] со значением по умолчанию, компилятор C# не преобразует значение в имя члена вызывающего.

Было бы удобно, если страницы MSDN описывали такие ограничения для проектов C++/CLI. Сэкономит нам много времени.