簡體   English   中英

使用反射或 IL 將自定義屬性添加到 ReturnParameter

[英]Adding custom attributes to ReturnParameter using reflection or IL

我正在嘗試使用 IL 在運行時創建一些類型。 我有一個必須復制的原始MethodInfo

var parameters = OriginalMethod.GetParameters();

MethodBuilder methodBuilder = Builder.DefineMethod(
    $"<{OriginalMethod.Name}>k__BackingMethod",
    OriginalMethod.Attributes,
    CallingConventions.HasThis,
    OriginalMethod.ReturnType,
    parameters.Select(i => i.ParameterType).ToArray()
);

foreach (var attribute in OriginalMethod.GetCustomAttributesData().ToCustomAttributeBuilder())
    methodBuilder.SetCustomAttribute(attribute);

foreach (var attribute in OriginalMethod.ReturnParameter.GetCustomAttributesData().ToCustomAttributeBuilder())
    methodBuilder.SetCustomAttribute(attribute); // <---- Problem here

ILGenerator il = methodBuilder.GetILGenerator();
// Some code removed for brevity

return methodBuilder;

如您所見,我可以成功復制方法級別的自定義屬性。 我什至可以獲取ReturnParameter上的屬性。 但是,我似乎無法向ReturnAttribute添加新屬性。 使用上面的代碼,return 屬性被應用為常規方法屬性。 知道我會怎么做這樣的事情嗎?

編輯:為ToCustomAttributeBuilder添加了代碼

internal static CustomAttributeBuilder[] ToCustomAttributeBuilder(this IEnumerable<CustomAttributeData> CustomAttributes)
=> CustomAttributes.Select(attribute => attribute.ToCustomAttributeBuilder()).ToArray();

internal static CustomAttributeBuilder ToCustomAttributeBuilder(this CustomAttributeData CustomAttribute)
{
    var attributeArgs = CustomAttribute.ConstructorArguments.Select(a => a.Value).ToArray();

    var propertyArgs = CustomAttribute.NamedArguments.Where(i => i.MemberInfo is PropertyInfo);
    var propertyInfos = propertyArgs.Select(a => (PropertyInfo)a.MemberInfo).ToArray();
    var propertyValues = propertyArgs.Select(a => a.TypedValue.Value).ToArray();
    
    var fieldArgs = CustomAttribute.NamedArguments.Where(i => i.MemberInfo is FieldInfo);
    var namedFieldInfos = fieldArgs.Select(a => (FieldInfo)a.MemberInfo).ToArray();
    var namedFieldValues = fieldArgs.Select(a => a.TypedValue.Value).ToArray();
    
    return new CustomAttributeBuilder(CustomAttribute.Constructor, attributeArgs, propertyInfos, propertyValues, namedFieldInfos, namedFieldValues);
}

您需要將自定義屬性應用於返回值參數,而不是方法:

ParameterBuilder returnValueParameterBuilder = 
    methodBuilder.DefineParameter(0, ParameterAttributes.Retval, parameterName: null);

foreach (var attribute in OriginalMethod.ReturnParameter.GetCustomAttributesData()
                                                        .ToCustomAttributeBuilder())
{
    returnValueParameterBuilder.SetCustomAttribute(attribute);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM