המרות ליהוק וסוג נתונים ב- VB.NET

ליהוק הוא תהליך להמרת סוג נתונים אחד למשנהו, למשל, מסוג שלם לסוג מחרוזת. כמה פעולות ב VB.NET דורשים סוגי נתונים ספציפיים כדי לעבוד. הליהוק יוצר את הסוג שאתה צריך. המאמר הראשון בסדרה דו-חלקית זו, המרות וסוגי נתונים ב- VB.NET, מציג ליהוק. מאמר זה מתאר את שלושת המפעילים שבהם תוכלו להשתמש בכדי להעביר VB.NET - DirectCast, CType ו- TryCast - ומשווה את הביצועים שלהם.

הביצועים הם אחד ההבדלים הגדולים בין שלושת מפעילי הליהוק על פי מיקרוסופט ומאמרים אחרים. לדוגמה, מיקרוסופט בדרך כלל נזהרת מזהיר כי "DirectCast... יכול לספק ביצועים טובים מעט יותר מ- CType בעת המרה לאובייקט מסוג נתונים וממנו." (דגש הוסף.)

החלטתי לכתוב איזה קוד כדי לבדוק.

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

instagram viewer

שלושת מפעילי הליהוק הם:

  • DirectCast
  • CType
  • TryCast

למעשה, בדרך כלל תגלו כי הדרישות של היישום שלכם יקבעו באיזה מפעיל אתם משתמשים. יש ל- DirectCast ו- TryCast דרישות צרות מאוד. כשאתה משתמש ב- DirectCast, על הסוג להיות ידוע כבר. למרות שהקוד ...

theString = DirectCast (האובייקט, מחרוזת)

... יתחבר בהצלחה אם ה- Objekt כבר לא מחרוזת, אז הקוד יזרוק חריג לזמן ריצה.

TryCast מגביל עוד יותר מכיוון שהוא לא יעבוד בכלל על סוגים "ערכיים" כמו מספר שלם. (מחרוזת היא סוג הפניה. למידע נוסף על סוגי ערכים וסוגי ייחוס, עיין במאמר הראשון בסדרה זו.) קוד זה ...

theInteger = TryCast (האובייקט, מספר שלם)

... אפילו לא להדר.

TryCast הוא שימושי כאשר אינך בטוח איזה סוג של אובייקט אתה עובד. במקום לזרוק שגיאה כמו DirectCast, TryCast פשוט לא מחזיר דבר. הנוהג הרגיל הוא לבדוק כלום לאחר ביצוע TryCast.

רק CType (ושאר המפעילים "המר" כמו CInt ו- CBool) ימירו סוגים שאינם קשורים בירושה כמו מספר שלם למיתר:

עמעום theString כמחרוזת = "1" עמעום את המספר כמספר שלם. theInteger = CType (theString, מספר שלם)

זה עובד מכיוון ש- CType משתמש ב"פונקציות עוזר "שאינן חלק מה .NET CLR (Common Language Runtime) כדי לבצע המרות אלה.

אך זכור כי CType ישליך גם חריג אם ה- String אינו מכיל משהו שניתן להמיר למספר שלם. אם יש אפשרות שהמחרוזת אינה מספר שלם כזה ...


עמעום theString כמחרוזת = "ג'ורג '"

... אז אף מפעיל ליהוק לא יעבוד. אפילו TryCast לא יעבוד עם מספר שלם מכיוון שזה סוג ערך. במקרה כזה, תצטרך להשתמש בבדיקת תוקף, כגון מפעיל TypeOf, כדי לבדוק את הנתונים שלך לפני שתנסה להעביר אותם.

התיעוד של מיקרוסופט עבור DirectCast מזכיר באופן ספציפי ליהוק עם סוג אובייקט, כך השתמשתי במבחן הביצועים הראשון שלי. הבדיקה מתחילה בעמוד הבא!

DirectCast בדרך כלל ישתמש בסוג אובייקט, אז זה מה שהשתמשתי במבחן הביצועים הראשון שלי. כדי לכלול את TryCast במבחן, כללתי גם חסימת If מכיוון שכמעט לכל התוכניות המשתמשות ב- TryCast יהיו כאלה. אולם במקרה זה היא לעולם לא תבוצע.

להלן הקוד שמשווה את שלושתן בעת ​​היצקת אובייקט למיתר:

עמעום את הזמן כשעוני סטופר חדשים () עמעום את המיתר כמו מחרוזת. עמעום theObject כאובייקט = "אובייקט" עמק את התיבות כמספר שלם = CInt (Iterations. טקסט) * 1000000. ' מבחן DirectCast. הזמן. התחל () עבור i = 0 לתיאורים. theString = DirectCast (האובייקט, מחרוזת) הבא. הזמן. תפסיק() DirectCastTime. טקסט = הזמן. חלף מיליוני שניות. ToString. ' מבחן CType. הזמן. איתחול() עבור i כמספר שלם = 0 לתמונות. theString = CType (האובייקט, מחרוזת) הבא. הזמן. תפסיק() CTypeTime. טקסט = הזמן. חלף מיליוני שניות. ToString. ' מבחן TryCast. הזמן. איתחול() עבור i כמספר שלם = 0 לתמונות. theString = TryCast (האובייקט, מחרוזת) אם הסטרינג הוא כלום אז. MsgBox ("זה לעולם לא אמור להציג") סוף אם. הבא. הזמן. תפסיק() TryCastTime. טקסט = הזמן. חלף מיליוני שניות. ToString.

נראה כי הבדיקה הראשונית הזו מראה שמיקרוסופט נמצאת ביעד. הנה התוצאה. (ניסויים עם מספר חזרות גדול יותר וקטן יותר כמו גם בדיקות חוזרות בתנאים שונים לא הראו הבדלים משמעותיים מתוצאה זו.)


לחץ כאן כדי להציג את האיור

DirectCast ו- TryCast היו דומים ב 323 ו 356 אלפיות השנייה, אך CType לקח זמן רב פי שלושה ב 1018 אלפיות השנייה. כשאתה מעביר סוגי הפניות כאלה אתה משלם עבור הגמישות של CType בביצועים.

אבל האם זה תמיד עובד ככה? הדוגמה של מיקרוסופט בדף שלהם עבור DirectCast שימושית בעיקר כדי לספר לך מה לא לעבוד באמצעות DirectCast, לא מה יהיה. להלן הדוגמה של מיקרוסופט:

עומק ש 'כאובייקט = 2.37. Dim i כמספר שלם = CType (q, מספר שלם) 'ההמרה הבאה נכשלה בזמן ריצה. Dim j כמספר שלם = DirectCast (ש ', מספר שלם) Dim f כמערכת חדשה. חלונות. טפסים. טופס. Dim c As System. חלונות. טפסים. שליטה. 'המרה הבאה מצליחה. c = DirectCast (f, מערכת. חלונות. טפסים. שליטה)

במילים אחרות, אתה לא יכול השתמש ב- DirectCast (או TryCast, למרות שהם לא מציינים את זה כאן) כדי להעביר סוג אובייקט לסוג שלם, אבל אתה פחית השתמש ב- DirectCast כדי להעביר סוג טופס לסוג בקרה.

בואו לבדוק את הביצועים של הדוגמה של מיקרוסופט למה יהיה לעבוד עם DirectCast. באמצעות אותה תבנית קוד המוצגת לעיל, החלף ...


c = DirectCast (f, מערכת. חלונות. טפסים. שליטה)

... לתוך הקוד יחד עם תחליפים דומים ל- CType ו- TryCast. התוצאות מעט מפתיעות.


לחץ כאן כדי להציג את האיור

DirectCast היה למעשה האיטי מבין שלוש הבחירות במהירות של 145 אלפיות השנייה. CType פשוט מהיר יותר במהירות של 127 אלפיות השנייה, אך TryCast, כולל חסימת If, הוא המהיר ביותר ב -77 אלפיות השנייה. ניסיתי לכתוב חפצים משלי:


Class ParentClass... סיום כיתה. כיתת ילדים. ירושה ParentClass... סיום כיתה. 

הגעתי לתוצאות דומות. נראה שאם אתה לא ליהוק סוג אובייקט, עדיף לך לא באמצעות DirectCast.