322. new T() and Activator CreateInstance

דיברנו כבר בעבר על הConstraint המיוחד where T : new() (טיפים מספר 33, 317).

מעניין להבין איך הוא עובד. ובכן, אם נכתוב קוד כזה:

1
2
3
4
public static T Create<T>() where T:new()
{
return new T();
}

נקבל את תוצאת הקימפול הזאת:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.method public hidebysig static !!T Create<.ctor T>() cil managed
{
.maxstack 2
.locals init (
[0] !!T CS$1$0000,
[1] !!T CS$0$0001)
L_0000: nop
L_0001: ldloca.s CS$0$0001
L_0003: initobj !!T
L_0009: ldloc.1
L_000a: box !!T
L_000f: brfalse.s L_001c
L_0011: ldloca.s CS$0$0001
L_0013: initobj !!T
L_0019: ldloc.1
L_001a: br.s L_0021
L_001c: call !!0 [mscorlib]System.Activator::CreateInstance<!!T>()
L_0021: stloc.0
L_0022: br.s L_0024
L_0024: ldloc.0
L_0025: ret
}

מה שאנחנו רואים כאן זה בעצם קריאה מורכבת לפונקציה Activator.CreateInstance<T>(). (עם התחשבות בboxים וכו’)

אם נקרא אודות התיעוד של הפונקציה הזו בMSDN, נראה שבעצם הפונקציה הזאת קיימת בשביל שימוש ב-new T().

לא ברור האם מבחינת ביצועים היא גרועה כמו Activator.CreateInstance (ראו גם טיפ מספר 139, 180), אבל אם נסתכל במימוש של שתי הפונקציות האלה בReflector, נראה שמדובר בשני מימושים שונים לחלוטין! (היינו מצפים שאחד יקרא לשני, או ששניהם יקראו לאותה פונקציה)

מה שנותן תקווה כי אולי המימוש הוא לא כל כך נורא.

אולי בהמשך נבצע השוואה בין 3 שיטות: Activator.CreateInstance(typeof(T)), new T() וקריאה רגילה לConstructor.

שבוע גנרי טוב!

שתף