public static class Class1 { public static string name1 = "name1"; public static string name2 = this.Name; } 

By name2 automatically assign the value of his name, without specifying the name in the string.

Is it possible somehow shorter than this, without specifying name2 a second time ?:

 public static string name2 = nameof(name2); 
  • 2
    Why this may be needed? - Andrey NOP
  • 3
    use nameof() - dmepty
  • one
    The nameof function, though in more sophisticated versions, the reflection will save you. - nick_n_a
  • Why do you need what you ask? - iluxa1810 1:23 pm
  • I'm here on the chicken guts fortune telling ... You need CallerMemberName . Ne? - Alexander Petrov

2 answers 2

Solution for .NET 4.5+ / .NET Core

 using System.Runtime.CompilerServices; public static class MyName { public static string Get([CallerMemberName] string s = "") { return s; } } public class Class1 { public static string name1 = "name1"; public static string name2 = MyName.Get(); } 

Note. The fact that when using the CallerMemberName field in the initializer, it returns the name of this field (and not the name of the constructor, which is actually a caller), is not documented. But it works.

Solution for older .NET versions

 using System; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; public static class MyName { static OpCode FindOpCode(short val) { OpCode ret = OpCodes.Nop; FieldInfo[] mas = typeof(OpCodes).GetFields(); for (int i = 0; i < mas.Length; i++) { if (mas[i].FieldType == typeof(OpCode)) { OpCode opcode = (OpCode)mas[i].GetValue(null); if (opcode.Value == val) { ret = opcode; break; } } } return ret; } static string GetFieldNameFromOffset(MethodBase mi, int offset) { MethodBody mb = null; string result = ""; //ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ‚Π΅Π»ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° mb = mi.GetMethodBody(); if (mb == null) throw new ApplicationException("Fatal error: GetMethodBody failed!"); //ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ IL-ΠΊΠΎΠ΄ var msil = mb.GetILAsByteArray(); //ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ располоТСн ΠΌΠ΅Ρ‚ΠΎΠ΄ var module = mi.Module; short op; int n = offset; //парсим IL-ΠΊΠΎΠ΄... while (true) { if (n >= msil.Length) break; //ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΊΠΎΠ΄ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ if (msil[n] == 0xfe) op = (short)(msil[n + 1] | 0xfe00); else op = (short)(msil[n]); //Π½Π°ΠΉΠ΄Π΅ΠΌ имя ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ OpCode opcode = FindOpCode(op); string str = opcode.Name; int size = 0; //Π½Π°ΠΉΠ΄Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ switch (opcode.OperandType) { case OperandType.InlineBrTarget: size = 4; break; case OperandType.InlineField: size = 4; break; case OperandType.InlineMethod: size = 4; break; case OperandType.InlineSig: size = 4; break; case OperandType.InlineTok: size = 4; break; case OperandType.InlineType: size = 4; break; case OperandType.InlineI: size = 4; break; case OperandType.InlineI8: size = 8; break; case OperandType.InlineNone: size = 0; break; case OperandType.InlineR: size = 8; break; case OperandType.InlineString: size = 4; break; case OperandType.InlineSwitch: size = 4; break; case OperandType.InlineVar: size = 2; break; case OperandType.ShortInlineBrTarget: size = 1; break; case OperandType.ShortInlineI: size = 1; break; case OperandType.ShortInlineR: size = 4; break; case OperandType.ShortInlineVar: size = 1; break; default: throw new Exception("Unknown operand type."); } size += opcode.Size; int token = 0; if (n > offset && (str == "stsfld" || str == "stfld")) { //Π½Π°ΠΉΠ΄Π΅ΠΌ Ρ‚ΠΎΠΊΠ΅Π½ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… поля token = (((msil[n + 1] | (msil[n + 2] << 8)) | (msil[n + 3] << 0x10)) | (msil[n + 4] << 0x18)); //Π½Π°ΠΉΠ΄Π΅ΠΌ ΠΏΠΎΠ»Π΅ Π² ΠΌΠΎΠ΄ΡƒΠ»Π΅ ΠΏΠΎ Ρ‚ΠΎΠΊΠ΅Π½Ρƒ var fi = module.ResolveField(token); result = fi.Name; return result; } n += size; //пропускаСм Π½ΡƒΠΆΠ½ΠΎΠ΅ число Π±Π°ΠΉΡ‚ΠΎΠ² } return result; } [MethodImpl(MethodImplOptions.NoInlining)] public static string Get() { //Π½Π°ΠΉΠ΄Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ var stack = new StackTrace(true); var frame = stack.GetFrame(1); var method = frame.GetMethod(); //Π½Π°ΠΉΠ΄Π΅ΠΌ имя поля ΠΏΠΎ ΡΠΌΠ΅Ρ‰Π΅Π½ΠΈΡŽ Π² IL var name = GetFieldNameFromOffset(method, frame.GetILOffset()); return name; } } public class Class1 { public static string name1 = "name1"; public static string name2 = MyName.Get(); } 

For the initializer of the name2 field in the constructor code, the compiler generates a sequence of IL call and stsfld instructions. The StackFrame.GetILOffset method allows us to get the call instruction offset in bytes relative to the beginning of the constructor code, and MethodInfo.GetMethodBody allows us to get the IL code of the constructor itself. To get FieldInfo, it is enough to find the instruction that follows the call, pull out the field metadata token and pass it to the Module.ResolveField method. From FieldInfo it is already easy to get the field name.

    Let's imagine the situation:

     Cat Tomas = new Cat(); Cat Daryl = Tomas; 

    In this case, both the Tomas and Daryl variables refer to the same object.

    What value should return if we Tomas.Name to Tomas.Name and what if we Daryl.Name to Daryl.Name ? How in theory should the language determine from which name the method call was made which returns the name?


    My guess in this case is that it is possible to make initialization of the variable name mandatory. Like

     Cat Tomas = new Cat("Tomas"); 

    This does not solve the problem, but it works in some cases. (in the example above, of course, will not work).

    ...........

    Purely in theory, you can come up with something with glassrays. But not the fact that it will work in the release build.

    ...........

    Purely in theory, it is possible to come up with something with reflection. But not the fact that it will always work as it should and does not produce false results, as in the example above.


    In general, I strongly advise not to do so at all in principle. Use nameof() in places where you need it. This is guaranteed not to bring problems.

    And also, most likely, you are moving in the wrong direction and have come up with the wrong solution to your task.