Search code examples
c#compact-frameworkattributesmarshallinggetcustomattributes

How do I GetCustomAttributes?


I have tried the following code using the 2.0 framework and I get an attribute back, but when I try this on the compact framework, it always returns an empty array. The MSDN documenation says its supported, am I doing something wrong?

  Test x = new Test();
  FieldInfo field_info = x.GetType().GetField("ArrayShorts");
  object[] custom_attributes = field_info.GetCustomAttributes(typeof(MarshalAsAttribute), false);

  [StructLayout(LayoutKind.Sequential)]
  public struct Test
  {
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
     public ushort[] ArrayShorts;
  }

Solution

  • EDIT 2

    So I'm checking with the CF team now but I believe you've found a bug. This shows it even better:

    public class MyAttribute : Attribute
    {
        public MyAttribute(UnmanagedType foo)
        {
        }
    
        public int Bar { get; set; }
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct Test
    {
        [CLSCompliant(false)]
        [MyAttribute(UnmanagedType.ByValArray, Bar = 4)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public ushort[] ArrayShorts;
    }
    
    class Program
    {
        static void Main(string[] args)
        {
    
            FieldInfo field_info = typeof(Test).GetField("ArrayShorts");
            object[] custom_attributes = field_info.GetCustomAttributes(typeof(MarshalAsAttribute), false);
            Debug.WriteLine("Attributes: " + custom_attributes.Length.ToString());
            custom_attributes = field_info.GetCustomAttributes(typeof(MyAttribute), false);
            Debug.WriteLine("Attributes: " + custom_attributes.Length.ToString());
            custom_attributes = field_info.GetCustomAttributes(typeof(CLSCompliantAttribute), false);
            Debug.WriteLine("Attributes: " + custom_attributes.Length.ToString());
        }
    }
    

    Under the full framework I get back this:

    Attributes: 1
    Attributes: 1
    Attributes: 1
    

    Under CF 3.5 I get this:

    Attributes: 0
    Attributes: 1
    Attributes: 1
    

    So you can see it's fully capable of returning an attribute, either custom or within the BCL, just not the MarshalAsAttribute.


    EDIT 3 Alright, I did a little more digging, and it turns out that the CF behavior is actually correct if you go by the spec. It goes against all logic, but it's right.