ארכיון תגיות: C#

דיסיריליזציה של XML מקוננים באמצעות XmlReader + XmlSerialization ב- C#

האתגר  – דיסיריליזציה מאוד מהירה של XML בכל גודל שהוא – בלי צריכת משאבים גבוהה.

כאשר עובדים עם קבצי XML גדולים , נרצה להפוך אותם לאובייקטים שלנו, שאיתם נוכל לעשות פעולות רגילות.

יחד עם זאת, המחלקה הרגילה לצורך כך, יכולה להתמודד עם קבצי XML בגודל קטן, אך בקבצי XML גדולים – היא צורכת משאבים רציניים (זיכרון וכו' )

בנוסף, קריאת XML עם מחלקת XmlReader היא הרבה יותר מהירה מאשר מחלקת XmlDocument

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

הפתרון – שימוש ב – XmlReader + XmlSerialization

נחלק את ההסבר ל-2 חלקים, חלק 1 יעסוק ב-Reader , וחלק שני בדיסיריליזציה.

חלק 1 – Xml.Reader

החלק של ה-Reader הולך כך : ניצור אוביקט Reader בתחילת הפעולה, ונשחרר את המשאבים בסוף הפעולה.

 /** Init XML reader */
 XmlReader reader = XmlReader.Create(fileName);


... Your code here
...
...

/** Close **/ 
 reader.Dispose();
  • הערה לגבי .net core : עדיף להשתמש במתודה Dispose ולא במתודה Close
    כי רק Dispose קיימת ב- .net core.

 

  • אם יש לנו בלוקים גדולים, אפשר ומומלץ ליצור אוביקט Reader נפרד עבורם – שמכיל רק את השורות של הבלוק הגדול שלנו, ולא מכיל את שאר השורות בקובץ

הנה דוגמא מלאה :

 // Position the reader on the second book node
 reader.ReadToFollowing("MyBigElement");
 
 // Create another reader that contains just the second book node.
 XmlReader readerMyBigElement = reader.ReadSubtree();

 // init new xmlSerlizer - To new instance of class MyWantedClass
 // Be Aware - MyWantedClass is the class that will get into 
 // the values from MyBigElement in the XML.
 XmlSerializer xmlSerlizer = new XmlSerializer(typeof(MyWantedClass));
 
 MyWantedClass myWantedClass;
 // Deserialize
 myWantedClass = (MyWantedClass)xmlSerlizer.Deserialize(readerMyBigElement);

 readerKoteretKovetz.Dispose();

הפתרון הזה מצריך יצירה מראש מחלקות עבור הבלוקים השונים ב-XML.

חלק 2 – דיסירליזציה

כאשר צריך להשתמש ב-Attributes  ( תיעוד על שימוש ב-attributes הספציפיים  – בקישור הזה ).

אני מתמצת כאן נקודות חשובות :

  • אם שם האלמנט בתוך ה-XML הוא בדיוק כמו שם המשתנה – אין צורך להשתמש ב-Attribute
  • בכל מקרה אחר – נשתמש ב-Attribute
  • דוגמא פשוטה ל- String
[XmlElement(ElementName = "My-Xml-Element-Name", IsNullable = true)]
public string myVariable;
  • משתנים במחלקה שלא קשורים לקובץ ה-XML, נסמן אותם ב- Attribute של XmlIgnore

 

  • טיפול ב-Null   :   בכל אלמנט שלא ידוע לנו אם הוא יגיע בוודאות, או שיגיע ללא ערך , או שיגיע null \ nil
    אז נוסיף את ההגדרה

    IsNullable = true
  • טיפול ב-Null עבור ערכים מספריים :  – אם המשתנה שצריך לקבל ערך הוא מסוג int \ decimal , אז עבור המקרים שבהם הערך יהיה ריק , צריך להגדיר אותם עם סימן שאלה בסוף, כדי שיוכלו לקבל ערך null
    לדוגמא
public int myVar
  • טיפול ב-Null עבור אובייקטים – לייצר את האובייקט מראש בזמן ההגדרה :
    MyObject myObject = new() myObject();
  • טיפול ב- Null עבור ערכי תאריך  – במקרה של תאריך, נצטרך לשים getter\setter מתאימים.
    בפירוט : נניח שהתאריך מגיע כ ddmmyyyy
    אז ניצור

    • משתנה מסוג string שמקבל את הערך המקורי
    • משתנה מסוג date עם getter + setter
    • ה-setter – בודק אם הערך המקורי הוא null ורק אם לא, אז הוא עושה לו Parse
    • ה-getter – מחזיר את התאריך.
[XmlIgnore]
 public DateTime dtRealDate { get; set; }

 
 [XmlElement(ElementName = "MyDateInXml", IsNullable = true)]
 public string MyDateBlaBla
 {
 get
 {
 return this.dtRealDate.ToString();
 }
 set
 {
 if (value != null)
 {
 this.dtRealDate = DateTime.ParseExact(value, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
 }
 }
 }
  • קינון :
    • נניח שיש לנו כמה בלוקים של XML בתוך הקובץ, כל בלוק עוסק בישות אחרת.
    • אז כל בלוק – הוא מחלקה נפרדת.
    • זאת אומרת שבתוך המחלקה של הבלוק הראשי, יהיו משתנים מסוג אוביקט הבלוק הרלוונטי 
    • ואז – כדי להתמודד עם Null , כמו שכבר כתבתי למעלה , ניצור כבר new instance בזמן הגדרת המשתנה.
      כך שבכל מקרה שהבלוק הזה יגיע ריק או null, לא נקבל Exception
    • אפשר גם לקנן לתוך List !!! וזה עובד היטב.
 [XmlElement(ElementName = "ElementThatArriveMultipleTimes", IsNullable=true)]
 public List<Product>productsList = new List<Product>();

 

כלים נחמדים לטיפול ב-XML וליצירת המחלקות

 

  • מיקרוסופט מציעה למי שמוריד את Windows SDK , כלי קטן שנקרא xsd.exe
    ובמידה ויש לכם קובץ xsd שמתאר את ה-XML שלכם, אז הכלי הזה יכול לייצר אוטומטית את המחלקות.
    אני לא מצאתי שהוא שימושי, כי הוא מייצר הרבה קוד זבל, ואין לי שליטה על כל המאפיינים שלו, אבל אולי למישהו אחר זה יכול לעזור ( שוב…בהנחה שיש לכם קובץ XSD שמתאר את ה-XML).
  • כדי לקרוא XML גדולים מאוד בצורה נוחה
    לא צריך עורך טקסט או IDE \ דפדפן – שמן הסתם יקרסו באמצע.
    אפשר להשתמש בכלי XML Explorer  שעובד ממש יפה , וגם מאפשר שאילתות XPATH בקלות.
    זה כלי אחד לדוגמא, ובטוח יש עוד כאלו https://xmlexplorer.codeplex.com/ 

בהצלחה!

 

מעבר מ-PHP ל – C# , ומ-Laravel אל ASP.NET MVC – רשמים ראשונים

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

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

ועכשיו לתכלס – ההבדלים העיקרים בין PHP ל- C# .

אז ראשית – צריך להבהיר מספר מושגים, כדי שלכל מי שקורא את הפוסט יהיה קל .

ה-Framework של C# מבית מיקרוסופט, נקרא ASP.NET MVC, וקיימת גם גירסה שונה שלו שמיועדת עבור API ונקראת WebAPI ( ניתנים לשילוב, אך בעיקרון – 2 מוצרים שונים).

והמקבילה בעולם ה-PHP שאיתה עבדתי בעיקר, הייתה ה-Framework המוביל כיום ב-PHP, שנקרא Laravel , גם אצלו קיימת גירסה ל-API שנקראת Lumen.

הבדלים ברמת מחיר :

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

הבדלים ברמת השפה – בין PHP ל- C# .

אז ההבדל העיקרי ביותר – הוא ש-C# מחייבת להצהיר על סוגי המשתנים, בניגוד ל-PHP.

מבחינת Syntax, השפות מאוד מאוד דומות, וכמעט אין הבדלים משמעותיים . נציין כמה הבדלים קטנים :

  • בהכרזה של namespace, ב-C# ,  צריך להכניס  את כל ה- קלאס תחתיו גם כן בתוך סוגרים מסולסלות { } .
  • המילה use מתחלפת במילה using.
  • אין triats ב-C#
  • יש  ב-C# משתנה מסוג List שעובד די יעיל ולא קיים ב-PHP ( יותר נכון, קיים, אך רק דרך תוספות)
  • יש מתודות מובנות ב- C# למחרוזות, מערכים , ועוד ( בסגנון של JS – שכל משתנה הוא אוביקט … רק הרבה יותר מתודות מובנות ) .
  • מימוש של Interface נעשה ב-C# עם נקודותיים, לעומת implements ב-php
  • במקום final עבור מתודות \ קלאסים שלא יורשים מהם, משתמשים ב-seald ב-c# .
  • קיים מבנה של Enum ב-C# שלא קיים ב-PHP ( למרות שקל מאוד לממש – מפתחים רבים פותחים מחלקה שמכילה Consts בלבד , והיא משמשת בתור enum )
  • שתי השפות יכולות לרוץ על כל מערכת הפעלה
    כן כן, גם למיקרוסופט יש גירסה ל-dot net שנקרא dot net core ורצה היטב על Linux .
  • ב-c# לפני הרצה צריך לבצע תהליך Build (קומפלייר)
    מה שנחסך מאיתנו כשעובדים ב-PHP
    זה יכול לקחת זמן לפעמים….וזה קטע מעצבן.

הבדלים מבחינת Enviroment  בין PHP ל- C# :

  • מנהל החבילות המוכר ב-PHP נקרא composer , בסביבת .Net קיים מנהל חבילות שנקרא NuGet
  • "על הנייר" נראה שיש פחות חבילות ל-C# , אבל זו השוואה ממש לא רלוונטית, כיוון שהרבה מאוד ספריות, מובנות כבר בתור השפה, ואין שום צורך בחבילה חיצונית.
    • דוגמא פשוטה לכך : ב-PHP נפוץ מאוד השימוש בספריה Carbon לצורך מניפולציות על תאריכים, לעומת זאת ב-C# , הספריה של DateTime כבר מובנה בשפה, ואין צורך לייבא אותה.
      נכון אומנם שגם ב-PHP יש ספרית DateTime, אך מהניסיון שלי, היא פחות נוחה לעבודה, וכיוון שכך – משתמשים ב-Carbon.
  • בסביבת מיקרוסופט, קיים IDE חזק, ללא תשלום, שנקרא Visual Studio , בא נגיד שאם מקבילים את זה לסביבת ה-PHP, אז זה כמו לקבל בחינם IDE ברמה של PHP Storm ( ואולי יותר מזה )
    • חיסרון מעצבן שלו  בכל זאת – זה שאין לו באופן מובנה ctrl+d לשכפול שורה, אך למרבה המזל, בגיגול פשוט, מוצאים תוספים שעושים זאת.
  • שרת Web – ב-PHP נהוג לעבוד עם Apache או Ngnix , לעומת סביבת dot net , שבה עובדים עם IIS.
  • אפליקציות Mobile – כאן יש יתרון עצום לסביבת מיקרוסופט, עם כלי שנקרא xamarin, ומאפשר לפתח אפליקציות שמתקפלות ל-Native , באותה שפה ( C# ) שבה אתה מפתח כרגיל.
    זה חוסך שימוש בפתרונות כמו PhoneGap \ Cordova וכדומה.
    והביצועים – בשמים.
  • כלי Debug :  ב-PHP נפוץ מאוד השימוש ב-xdebug , שההתקנה שלו עשויה להיות לפעמים סיזיפית ( חפשו ב-Youtube ותראו את כמות המדריכים בנושא ) .
    ה-Xdebug הוא תוספת ל-PHP שמאיטה מאוד את ההרצה.
    ב-C#, כלי ה-Debug מובנה בתוך Visual Studio, גם מאט מעט את ההרצה, אך פחות לעומת Xdbeug בתחושה האישית שלי.
  • הבדלים בתיעוד : 
    • מיקרוסופט מנצחת בגדול, הכל מתועד עד לפרטי פרטים,
      יחד עם זאת, קיים חיסרון של "יותר מדי מידע" ולפעמים קשה להבין איפה נמצא כל דבר בתור הררי התיעוד של מיקרוסופט.
    • לנקודה הזו יש יתרון מסויים נוסף מה קורה כאשר יש משהו לא ברור בתיעוד הרשמי ? – התיעוד של Laravel הוא מעולה בעיני, אך יש קטעים מסויימים בהם הוא כתוב גרו ( למשל ההסברים על IOC וקונספטים אחרים ) ובמקרה כזה – אין הרבה אפשרויות חוץ מלהתחיל לחפש בפורומים – שזה חיסרון .
      במיקרוסופט – בגלל עודף המקורות הרשמיים, אין הרבה צורך בפורומים. כי כמעט כל מה שתחפש כתוב בתיעוד הרשמי.

הבדלים ברמת ה- Framework  בין Laravel אל- ASP.NET MVC:

  • במבט ראשון, יש המון דברים מקבילים בין ASP.NET MVC ל- C#
  • זה מעלה מחשבות קלות של "מי העתיק ממי" אם כי, אני נוטה להניח שמיקרוסופט היו ראשונים, ו-Taylor היוצר של Laravel פשוט מימש את הדברים ב-Laravel כמו שהוא הכיר אותם לפני כן בסביבת מיקרוסופט.
  • לשתיהם יש ORM חזק, המקבילה של Eloquent ב-Laravel נקראת Entity ב-.Net
  • למרות שקיבלתי רושם שמפתחים רבים מסתייגים משימוש ב-Entity, לאחר מחקר קטן, זה כנראה חסר בסיס ( אולי בעבר היא הייתה נחותה מבחינת ביצועים, אך כיום ממש לא כך). מבחינת ביצועים – היא בסדר גמור לכל השאילתות הרגילות והפשוטות, כך שבשיקול עלות-תועלת של מהירות פיתוח מול ביצועים – זה בהחלט אופציה טובה.
  • גודל ההשקעה בפרוייקט – Laravel היא בסופו של דבר יציר כפיו של אדם אחד, עם מעט שותפים. קיימת כמובן קהילת Open Source גדולה וכו', אבל הוא ה-PO שלה חד משמעית (טיילור).
    ב-ASP.NET MVC זה מוצר של חברת ענק, ולפחות מבחינתי האישית זה היווה שיקול משמעותי בהחלטה לעבור, היות ואני לא נסמך על אדם אחד, עם קהילת קוד פתוח ( גדולה, ופעילה ככל שתהיה, כל עוד אין אינטרס כספי, לדעתי האישית, זה סיכון מסוים שצריך להילקח בחשבון).

הבדלים ברמת ביצועים בין C# ל- PHP :

  • אין כלל ספק ש-C# עולה בכמה רמות על PHP מבחינת ביצועים.
  • זה מורגש מעט בקטעי קוד שמבצעים עיבודים רציניים.
  • שפת C# היא שפה חצי-מתקמפלת , זה משליך על הביצועים משמעותית לטובה לעומת PHP.
  • עוד דברים שמשפיעים על ביצועים :
    • ב–C# התוכנה "נשארת" במצב ריצה כל הזמן, לעומת PHP שבה כל Request הוא מופע עצמאי שמתחיל מחדש.
    • החיבור ל-DB הוא קבוע ב-C#, לעומת PHP שבה החיבור נוצר בכל Request מחדש (לפי הצורך כמובן ) .
  • בקטעי קוד קטנים, אין הבדל מורגש בכלל בין השפות.
  • אומנם ב-PHP יש פתרונות לעבודה במקביל, אבל הם לא פשוטים ליישום כמו ב-C#  ( מספר תהליכים יחד).

 

סיכום – PHP לעומת C#

עניינים של בחירת שפה הפכו להיות נושאים "דתיים" לפעמים, אבל תכלס, כשבאים לבחון איזה כלי יותר טוב, בלי לערב שיקולים "כאילו-אידיאולוגים" של קוד פתוח וכו' – אז נראה שמיקרוסופט נותנת יותר ב-C# +ASP.NET MVC  לעומת PHP עם Laravel

יחד עם זאת, חייבים להודות שאם מישהו מחפש ללמוד במהירות שפת Web – אז PHP עדיפה משמעותית ..פשוט פותחים עמוד html, כותבים תגית php וזה רץ….

לדעתי, עקומת הלמידה לא כל כך משמעותית כדי להצדיק להתחיל עם PHP, בוא נגיד שאילו הייתי היום חוזר לאחור, אז הייתי מתחיל מראש עם c# , אבל כדי ללמד את הילדים בבית תיכנות הייתי בוחר ב-PHP .

המנצחת בעיני היא C# .

בהצלחה.