2016-04-08 17 views
1

In C# und VB.Net kann ich das CallerMemberNameAttribute verwende den Namen des Aufrufer als String zu erhalten:C++/CLI: Wie verwende ich das CallerMemberNameAttribute in C++/CLI?

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

Ich möchte das gleiche in C++/CLI tun, aber irgendwie kann ich es nicht bekommen Arbeiten. Ich habe mehrere Konstruktionen ausprobiert und frage mich, ob der C++/CLI-Compiler dieses Attribut unterstützt.

Hier ist ein (vereinfachtes) Umsetzung:

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

Wenn dieses Verfahren in einer Anwendung C# Aufrufen der Wert von name null ist. Auch versucht mit dem Attribut DefaultParameterValue aber es hat auch nicht geholfen. Jetzt haben wir keine Ideen mehr.

Offensichtliche Antwort wäre, warum nicht in C# implementieren? Nun, in diesem speziellen Fall bin ich auf C++/CLI beschränkt.

+0

Kein Punkt beim Versuch, dies ist nicht im C++ - Compiler implementiert. C++/CLI wurde 2005 eingefroren. Sie müssen die [StackTrace-Klasse] (http://stackoverflow.com/a/2652591/17034) verwenden. –

+0

Seien Sie sich bewusst, dass der Vorschlag von Hans eine schwerwiegende Leistungseinbuße beinhaltet. –

Antwort

1

Ich habe Reflector verwendet, um die Unterschiede zwischen der C++/CLI und der C#/VB.Net Version zu sehen, und sie sahen genau gleich aus.

Dann ILDASM verwendet und jetzt denke ich, ich weiß, warum es nicht funktioniert (nach dem Lesen dieser post).

Hier ist der IL-Code:

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-Code von VB.Net von C# unterscheidet sich wie folgt:

.param [1] = nullref 

Ich vermute das wegen der C++/CLI gibt DefaultParameterValue statt der Initialisierung von .param [1] mit einem Standardwert aus, konvertiert der C# -Compiler den Wert nicht in den Namen des aufrufenden Members.

Wäre nützlich, wenn die MSDN-Seiten solche Einschränkungen für C++/CLI-Projekte beschreiben. Würde uns viel Zeit sparen.