Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
  }
like image 911
SwDevMan81 Avatar asked Aug 12 '09 21:08

SwDevMan81


People also ask

What is GetCustomAttributes?

GetCustomAttributes(MemberInfo, Type) Retrieves an array of the custom attributes applied to a member of a type. Parameters specify the member, and the type of the custom attribute to search for. GetCustomAttributes(Assembly, Type, Boolean) Retrieves an array of the custom attributes applied to an assembly.

What are attributes C#?

In C#, attributes are classes that inherit from the Attribute base class. Any class that inherits from Attribute can be used as a sort of "tag" on other pieces of code. For instance, there is an attribute called ObsoleteAttribute . This is used to signal that code is obsolete and shouldn't be used anymore.


1 Answers

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.

like image 89
ctacke Avatar answered Oct 13 '22 22:10

ctacke