简体   繁体   中英

How to get the base constructor calling parameters with Reflection

How to get the hard-coded parameter that the sub-class constructor is used to call the base-class constructor?

public class BaseMessage
{
    public BaseMessage(string format, params string[] parameteres)
    {
    }
}

public class HelloMessage : BaseMessage
{
    public HelloMessage(string name) : base("Hello {0}", name)
    {
    }
}

public class IntroductionMessage : BaseMessage
{
    public IntroductionMessage(string name, string myName) : base("Hello {0}, I am {1}", name, myName)
    {
    }
}

I would like to get all the hard-coded formatting string for the sub-classes of BaseMessage, ie "Hello {0}" and "Hello {0}, I am {1}"

At the reflection level , the only place this exists is in the method body of the constructor, which gets compiled as ( HelloMessage ):

.method public hidebysig specialname rtspecialname instance void
    .ctor(string name) cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldstr "Hello {0}"
    L_0006: ldc.i4.1 
    L_0007: newarr string
    L_000c: dup 
    L_000d: ldc.i4.0 
    L_000e: ldarg.1 
    L_000f: stelem.ref 
    L_0010: call instance void BaseMessage::.ctor(string, string[])
    L_0015: ret 
}

or ( IntroductionMessage ):

.method public hidebysig specialname rtspecialname instance void
    .ctor(string name, string myName) cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldstr "Hello {0}, I am {1}"
    L_0006: ldc.i4.2 
    L_0007: newarr string
    L_000c: dup 
    L_000d: ldc.i4.0 
    L_000e: ldarg.1 
    L_000f: stelem.ref 
    L_0010: dup 
    L_0011: ldc.i4.1 
    L_0012: ldarg.2 
    L_0013: stelem.ref 
    L_0014: call instance void BaseMessage::.ctor(string, string[])
    L_0019: ret 
}

So; via reflection you would have to get the method body ( MethodInfo.GetMethodBody().GetILAsByteArray() ) and manually deconstruct it (noting that you'll have compiled IL to deal with, not the text version I've shown). This is possible , but is massively over-complicated for what you probably want. There are runtime IL disassembly tools, but... again: massively overkill here.

I would recommend either:

  • just look at what values arrive in format in the BaseMessage at runtime
  • use a compile-time tool such as an analyzer - or parse the source with Roslyn - and get the data at build
  • something involving attributes or properties; it is pretty easy to get values from attributes or properties

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM