171. Attribute GetCustomAttributes

כתבתי בטיפ על AttributeUsage שאפשר לשים Inherited = true, ואז אם נקרא לGetCustomAttributes עם הפרמטר true, נקבל את הAttribute, גם אם הMember נדרס במחלקות הבנות.

אכן, אם נעשה משהו כזה:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ParentClass
{
[Cool]
public virtual void NiceMethod()
{
}
}
public class ChildClass : ParentClass
{
public override void NiceMethod()
{
Console.WriteLine("This method is nice!");
}
}

ונקרא לשורות הבאות:

1
2
3
4
5
6
7
8
MethodInfo niceMethodInfo =
typeof (ChildClass).GetMethod("NiceMethod");
object[] niceMethodInfoAttributes =
niceMethodInfo.GetCustomAttributes(true);
if (niceMethodInfoAttributes.Length > 0)
{
// true
}

נכנס לתנאי.

זה יפה, אבל תכף יבוא מישהו ויגיד שהטיפ היומי הוליך אותו שולל. למה?

כי אם נעשה אותו הדבר עם Property:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ParentClass
{
[Cool]
public virtual string NiceProperty
{
get
{
return string.Empty;
}
}
}
public class ChildClass : ParentClass
{
public override string NiceProperty
{
get
{
return "This property is nice!";
}
}
}

ונקרא לאותן שורות:

1
2
3
4
5
6
7
8
9
10
PropertyInfo nicePropertyInfo =
typeof (ChildClass).GetProperty("NiceProperty");
object[] nicePropertyInfoAttributes =
nicePropertyInfo.GetCustomAttributes(true);
if (nicePropertyInfoAttributes.Length > 0)
{
// false
}

לא נכנס לתנאי!


מה לעזאזל קורה כאן?

לדעתי מדובר בבאג, ואם נסתכל בReflector על RuntimePropertyInfo (זהו המימוש של המחלקה האבסטרקטית PropertyInfo) על המתודה

1
2
3
4
5
6
public override object[] GetCustomAttributes(bool inherit)
{
return CustomAttribute.GetCustomAttributes
(this,
typeof (object) as RuntimeType);
}

לא כל כך מעניין אותנו מה עושה הפונקציה CustomAttribute.GetCustomAttributes, אבל שימו לב להתעלמות המדהימה מהפרמטר inherit.

לא כל כך ברור…


מה אפשר לעשות?

אחד התותחים האמיתיים נתקל בבעיה זו ומצא לה פתרון. מסתבר שקיימת פונקציה בשם Attribute.GetCustomAttributes שיודעת לטפל בProperties:

1
2
3
4
5
6
7
8
9
10
PropertyInfo nicePropertyInfo =
typeof (ChildClass).GetProperty("NiceProperty");
object[] nicePropertyInfoAttributes =
Attribute.GetCustomAttributes(nicePropertyInfo, true);
if (nicePropertyInfoAttributes.Length > 0)
{
// true
}

האם הפונקציה הזו יודעת לעבוד עם כל הMemberInfoים בצורה טובה? לא בדקתי, אבל במידה ואתם נתקלים בבעיה זו, כדאי לנסות את פתרון זה.

סופ"ש בר סגולה

שתף