LiteWait

I've got a custom attribute I can't seem to pull out by distinct type:

This returns null...

Norris.Broker.BusinessObject.NorrisFieldIdAttribute[] attrs =
(Norris.Broker.BusinessObject.NorrisFieldIdAttribute[])
propInfo.PropertyType.GetCustomAttributes(
typeof(Norris.Broker.BusinessObject.NorrisFieldIdAttribute), false);

whereas this returns an array of attributes of the same type...

object[] o = propInfo.GetCustomAttributes(false);

How can this be I have defined the following:

[AttributeUsage(AttributeTargets.Property,AllowMultiple=false)]
public class NorrisFieldIdAttribute : System.Attribute
{
...

[Norris.Broker.BusinessObject.NorrisFieldId(5784)]
public int l_job_number
{
....

Just doesn't make sense to me that I can get the attributes generically, but not by type.


Re: Visual C# General GetCustomAttributes for a specific type always returns null

TaylorMichaelL

You are trying to retrieve the attribute(s) from the property's type rather than the property definition itself. Your two code samples are not the same. Call GetCustomAttributes on the propInfo object rather than PropertyType.

propInfo.GetCustomAttributes(typeof(...), false);

Michael Taylor - 10/29/07

http://p3net.mvps.org





Re: Visual C# General GetCustomAttributes for a specific type always returns null

LiteWait

Sorry that was me messing around with finding a way to make it work. I change the code (back) to:

Norris.Broker.BusinessObject.NorrisFieldIdAttribute[] attrs =
(Norris.Broker.BusinessObject.NorrisFieldIdAttribute[])
propInfo.GetCustomAttributes(
typeof(Norris.Broker.BusinessObject.NorrisFieldIdAttribute), false);

And I still get null :-(
Thanks anyway.




Re: Visual C# General GetCustomAttributes for a specific type always returns null

TaylorMichaelL

Please post the definition of the property that you are trying to retrieve the attributes of. Include the attributes you defined. Also, did you try just capturing the return value as an object array rather than doing a typecast at the same time Shouldn't matter but just in case.

Michael Taylor - 10/29/07

http://p3net.mvps.org





Re: Visual C# General GetCustomAttributes for a specific type always returns null

LiteWait

[AttributeUsage(AttributeTargets.Property,AllowMultiple=false)]
public class NorrisFieldIdAttribute : System.Attribute
{
private int fieldId;

public int FieldId
{
get { return fieldId; }
set { fieldId = value; }
}


public NorrisFieldIdAttribute(int fieldId)
{
this.fieldId = fieldId;
}
}

I did a typecast...

Norris.Broker.BusinessObject.NorrisFieldIdAttribute[] attrs =
(Norris.Broker.BusinessObject.NorrisFieldIdAttribute[])
propInfo.GetCustomAttributes(
typeof(Norris.Broker.BusinessObject.NorrisFieldIdAttribute), false);

One more thing "attrs" returns an empty array instead of null, I misposted.

Thank for the help.






Re: Visual C# General GetCustomAttributes for a specific type always returns null

LiteWait

[Norris.Broker.BusinessObject.NorrisFieldId(5784)]
public int l_job_number
{
get { return this.CheckSecurityReadInt(_l_job_number); }
set { this.CheckSecurityChange(_l_job_number, value); }
}




Re: Visual C# General GetCustomAttributes for a specific type always returns null

TaylorMichaelL

Ok. Now can you confirm that the property info structure you retrieved matches the property value You specified false for the second parameter to GetCustomAttributes so attributes obtained through inheritance will be ignored. This can introduce an issue if you are dealing with derived classes. Are you dealing with inheritance in any way such as by using an instance of a derived class to retrieve the property information

Also, try to remove the typecast and just retrieve the object array directly. There might be a conversion issue causing problems although I would have expected an exception.

Michael Taylor - 10/29/07

http://p3net.mvps.org





Re: Visual C# General GetCustomAttributes for a specific type always returns null

LiteWait

PropertyInfo structure does match,

I changed the second parameter to true and it had no effect... return value is still an empty array.

What gets me is if I look at the return value in the debugger from:

object[] o = propInfo.GetCustomAttributes(false);

It indeed does have the Attribute of the type I expected.






Re: Visual C# General GetCustomAttributes for a specific type always returns null

LiteWait

This is just daffy...

object[] o = propInfo.GetCustomAttributes(false);
foreach (object oo in o)
{
Console.WriteLine("Type = " + oo.GetType().ToString());
Norris.Broker.BusinessObject.NorrisFieldIdAttribute nfa =
oo as Norris.Broker.BusinessObject.NorrisFieldIdAttribute;
}

Console.Writeline prints:

Type = Norris.Broker.BusinessObject.NorrisFieldIdAttribute

But casting it to that type returns null ! ! !




Re: Visual C# General GetCustomAttributes for a specific type always returns null

TaylorMichaelL

That's what I was suspecting. Arrays are not type convertible between each other in most cases. For example you can't convert a float array to a double array by a simple typecast. In the case of the function in question it is returning an object array so it won't let you convert it to a strongly typed array directly. I'm a little surprised you didn't get a runtime error. As an example the following code will work:

Code Block

object[] Foo ( )
{
return new string[] { "First", "Second", "Third" };
}

string[] values = (string[])Foo();

because the return value is truly a string array but the following code will generate a runtime error:

Code Block

object[] Foo ( )
{

return new object[] { "First", "Second", "Third" };
}

string[] values = (string[])Foo();

You'll need to treat the array as an object array until you get it locally. You can, however, use a for-each loop with the strongly typed attribute:

Code Block

foreach(MyAttribute attr in pi.GetCustomAttributes(...))

{
};

Michael Taylor - 10/29/07

http://p3net.mvps.org





Re: Visual C# General GetCustomAttributes for a specific type always returns null

TaylorMichaelL

It isn't really bizarre. You are making one false assumption. You are assuming that all elements in the array are the same and hence the CLR should be able to figure it out but that is not a valid assumption unless the CLR first traverses all elements in the array to ensure that it is true. It also might only be true at the very moment in time when the CLR checked it but not true thereafter. Case in point:

object[] values = new object[] { "First", "Second", "Third" };

string[] stringValues = (string[])values;

At this point the CLR could traverse the list and verify that the elements are all strings. But at any point after this it might not be true:

values[1] = 10;

Now if I start enumerating stringValues bad things will happen as one of the elements is no longer a string. Instead the CLR follows the more limited, faster, safer approach of only allowing the conversion if the actual base type (the array type) matches the cast. If it does then it is allowed, if it doesn't then it should error out.

Michael Taylor - 10/29/07

http://p3net.mvps.org





Re: Visual C# General GetCustomAttributes for a specific type always returns null

LiteWait

Ok, just tried:

foreach (Norris.Broker.BusinessObject.NorrisFieldIdAttribute nfa in propInfo.GetCustomAttributes(false))
{
}

Throws an exception:

Unable to cast object of type 'Norris.Broker.BusinessObject.NorrisFieldIdAttribute' to type 'Norris.Broker.BusinessObject.NorrisFieldIdAttribute'.

If it can't cast it to it's own type what can it cast it to :-) FYI there is only one object in the array,




Re: Visual C# General GetCustomAttributes for a specific type always returns null

TaylorMichaelL

Are you dealing with multiple assemblies It sort of sounds like the attribute you compiled your code against doesn't match the assembly where the attribute was defined for the object you're reflecting against. Even though the name(s) match the types are different. If you are dealing with multiple assemblies then take a look at the attribute type in the debugger and verify the attribute is coming from the same assembly as the object's attribute that you are reflecting on.

Ah, scratch that. You didn't specify the attribute type to retrieve so it is getting them all. Try this:

foreach(MyAttribute attr = pi.GetCustomAttributes(typeof(MyAttribute), false))
{
};

Michael Taylor - 10/29/07

http://p3net.mvps.org





Re: Visual C# General GetCustomAttributes for a specific type always returns null

LiteWait

Yes they are in multiple assemblies. However I tried what you said:

foreach (Norris.Broker.BusinessObject.NorrisFieldIdAttribute nfa in
propInfo.GetCustomAttributes(typeof(Norris.Broker.BusinessObject.NorrisFieldIdAttribute),false))
{
}

and it returns an empty array (I never get into the foreach).

I checked the versions and they seem to be the same. I am going to move that attribute into this assembly as a test (I bet it works) whcih means there is something about being in the other assembly that is stopping from working.

Thanks for all your help.




Re: Visual C# General GetCustomAttributes for a specific type always returns null

TaylorMichaelL

For clarification, in .NET a type is guaranteed unique by combining its name with the assembly it came from. Therefore a type called T1 in assembly A is completely independent of type T1 in assembly B. The compiler will complain if it runs across both of them at the same time. .NET does not do type-name equivalence. Now, if type T1 is in assembly B and assembly A and assembly C both reference assembly B then they both can use T1 as there is only one definition.

Michael Taylor - 10/29/07

http://p3net.mvps.org