Cómo obtener los atributos personalizados de un método?
Suponiendo que tenemos un método definido como se muestra a continuación:
public class SomeClass
{
[My("beautifulName")]
public void DoSomeThing()
{
// lo que sea.
}
}
La clase public MyAttribute : Attribute
tiene las siguientes propiedades:
public string Name { get; init; }
public MyAttribute(string name) => Name = name;
Ahora tenemos un volcado de memoria de esta aplicación, podemos usar ClrMD para encontrar fácilmente el tipo SomeClass
y luego podemos encontrar fácilmente el método DoSomeThing
de ClrMethod. Ahora, ¿cómo puedo encontrar la instancia correspondiente de MyAttribute
y obtener el valor de beautifulName
?
davy.ai
Para encontrar la instancia correspondiente de
MyAttribute
y obtener el valor debeautifulName
, puede seguir los siguientes pasos:ClrType
que representa el tipoSomeClass
utilizando ClrMD.ClrType someClassType = runtime.GetTypeByName("SomeClass");
ClrMethod
que representan todos los métodos en el tipoSomeClass
.IEnumerable<clrmethod> methods = someClassType.Methods;
ClrMethod
específico que representa el métodoDoSomeThing
.ClrMethod doSomethingMethod = methods.First(m => m.Name == "DoSomeThing");
MetadataToken
deldoSomethingMethod
.int doSomethingMethodToken = doSomethingMethod.MetadataToken;
MethodDesc
que representa eldoSomethingMethod
utilizando Windbg/SOS.!dumpmd -md <dosomethingmethodtoken>
MethodTable
que representa la instancia deSomeClass
.!dumpobj <someclassinstanceaddress>
EEClass
que representa la instancia deSomeClass
.!DumpClass <someclassinstanceaddress>
MethodTable
que representa la instancia deSomeClass
.!DumpMT -md <someclassinstancemethodtabletoken>
MethodInfo
que representa el métodoDoSomeThing
.!DumpMD -md <someclassinstancemethodtabletoken> -tid <threadid> -private
MethodDesc
que representa el métodoDoSomeThing
.!clrstack -a <threadid> // Para encontrar la dirección del marco de la pila
!u <dosomethingmethodaddress> // Para desensamblar y encontrar la dirección de MethodDesc
CustomAttributeData
que representa la instancia deMyAttribute
.CustomAttributeData myAttributeData = doSomethingMethod.GetCustomAttributesData().First(a => a.AttributeType == typeof(MyAttribute));
Name
de la instancia deMyAttribute
.string beautifulName = myAttributeData.ConstructorArguments[0].Value.ToString();