Using Reflection.Emit to copy a custom attribute to another method-Collection of common programming errors

The answer you (frjames) posted is close, but doesn’t account for property initializers like…

[ServiceBehavior(Name="ServiceName")]

However, the idea of converting CustomAttributeData to a CustomAttributeBuilder for use in Reflection.Emit is right on.

I ended up having to do this for an open source project (Autofac) and came up with this extension method:

public static CustomAttributeBuilder ToAttributeBuilder(this CustomAttributeData data)
{
  if (data == null)
  {
    throw new ArgumentNullException("data");
  }

  var constructorArguments = new List();
  foreach (var ctorArg in data.ConstructorArguments)
  {
    constructorArguments.Add(ctorArg.Value);
  }

  var propertyArguments = new List();
  var propertyArgumentValues = new List();
  var fieldArguments = new List();
  var fieldArgumentValues = new List();
  foreach (var namedArg in data.NamedArguments)
  {
    var fi = namedArg.MemberInfo as FieldInfo;
    var pi = namedArg.MemberInfo as PropertyInfo;

    if (fi != null)
    {
      fieldArguments.Add(fi);
      fieldArgumentValues.Add(namedArg.TypedValue.Value);
    }
    else if (pi != null)
    {
      propertyArguments.Add(pi);
      propertyArgumentValues.Add(namedArg.TypedValue.Value);
    }
  }
  return new CustomAttributeBuilder(
    data.Constructor,
    constructorArguments.ToArray(),
    propertyArguments.ToArray(),
    propertyArgumentValues.ToArray(),
    fieldArguments.ToArray(),
    fieldArgumentValues.ToArray());
}

That one accounts for all the ways to initialize the attribute.