317. GenericParameterAttributes

פגשנו בעבר (טיפ מספר 29) את הFeature של Generic Constraints ואת את הGeneric Constraints המיוחדים שאפשר לשים לפרמטרים גנריים (טיפים מספר 31,33).

בטיפ מספר 141 ראינו שאפשר לגלות איזה Constraintים יש על Type שמייצג פרמטר גנרי כלשהו. מסתבר שדרך זו נותנת לנו את הGeneric Constraints הרגילים, כלומר מאיזה טיפוסים על הפרמטר הגנרי שלנו צריך לרשת או לחלופין איזה ממשקים הוא צריך לממש.

לפעמים מעניין אותנו לדעת אם יש על פרמטר גנרי אחת מההגבלות המיוחדות, כי אחרת נחטוף Exception כשננסה לקרוא לMakeGenericMethod/MakeGenericType (טיפים מספר 140, 149) עם פרמטר גנרי לא מתאים.

אם נחפש את הConstraintים המיוחדים בדרך אליה אנו רגילים, אנחנו נתאכזב לראות שהם אינם מופיעים ב GetGenericParameterConstraints. מסתבר שיש דרך אחרת לגלות איזה Constraintים מיוחדים יש לטיפוס גנרי, והיא כזאת:

1
2
3
public static void MyGenericMethod<T>() where T : new()
{
}

נשיג את הMethodInfo:

1
2
MethodInfo methodInfo =
this.GetType().GetMethod("MyGenericMethod");

כעת יש לType איזשהו Property בשם GenericParameterAttributes שהוא Enum עם הערכים הבאים:

1
2
3
4
5
6
7
8
9
10
11
12
[Flags]
public enum GenericParameterAttributes
{
None = 0,
Covariant = 1,
Contravariant = 2,
VarianceMask = Contravariant | Covariant,
ReferenceTypeConstraint = 4,
NotNullableValueTypeConstraint = 8,
DefaultConstructorConstraint = 16,
SpecialConstraintMask = DefaultConstructorConstraint | NotNullableValueTypeConstraint | ReferenceTypeConstraint,
}

שימו לב שהוא Enum של Flags (ראו טיפ מספר 22) ולכן נוכל לבדוק אם יש Constraint מסוים בצורה הבאה (ראו גם טיפ מספר 72):

1
2
3
4
5
if (genericArgument.GenericParameterAttributes.HasFlag
(GenericParameterAttributes.DefaultConstructorConstraint))
{
// true, because T : new()
}

באופן דומה יש ערכים מתאימים בEnum לבדיקות אחרות, למשל האם מתקיים שT הוא struct, class וכו’.

משהו שאולי כדאי לדעת, זה שאם שמתם משהו כזה:

1
2
3
public static void MyGenericMethod<T>() where T : struct
{
}

הEnum יכיל גם DefaultConstructorConstraint וגם NotNullableValueTypeConstraint, כי לכל Value Type יש Constructor דיפולטי. (ראו גם טיפ מספר 131)

המשך יום גנרי עם תנאים מיוחדים טוב.

שתף