יום שבת, 29 בדצמבר 2012

UTF-8 VS. UTF-16

קורה לא פעם, שאנחנו עובדים עם טקסט בקידודים שונים. לא מזמן יצא לי לשאול את עצמי למה יש קטעי קוד שמקודדים ב UTF-16.
לפני שנדבר על UTF8, UTF16 אנחנו צריכים להבין מה זה ASCII:

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

עם השנים החליף סטנדרט ה-UTF8/16 את ה-ASCII.


אז אנחנו מבינים מה זה ASCII.

אז מתי נשתמש ב UTF8?
  1. UTF8 תואם ל ASCII. לכן אם יש לנו מערכת ישנה שהשתמשה בקידוד ASCII, נוכל להניח ש UTF8 יהיה תואם.
  2. מבחינת צריכת זיכרון UTF8 עדיף: הוא משתמש בבית אחד כיחידה הקטנה ביותר, ו UTF16 משתמש כשני בתים ליחידה הקטנה ביותר. אך שימו לב!! UTF16 גם יכול להשתמש ב 3 ו 4 בתים (באג נפוץ זה שמתכנתים נוטים לחשוב ש UTF16 משתמש רק בשני בתים).
  3. מתי UTF16 צורך פחות זכרון? כאשר ה ASCII לא דומיננטי. כאשר הטקסט מכיל אותיות יפניות, סיניות,קוריאניות, הודיות, תווי מוזיקה UTF16 משתמש בפחות בתים ( 2 בתים בהשוואה ש UTF8 יכול לצרוך 3 בתים או יותר בנ"ל)
  4. אם אנחנו צריכים להעביר מידע ברשת, נרצה לקודד ב UTF8, ככה לא נצטרך לדאוג לחיבור בתים שונים ליצירת אות בעת קבלת המידע. כל אות תהיה מורכבת מבית אחד (לרוב כמובן).
  5. יש הטוענים ששימוש בקידוד  UTF16 טוב עבור עיבוד מידע בזכרון.
המלצתי היא להחליט על הקידוד הנכון רק לאחר שבוחנים את הטקסט שאנחנו הולכים לקודד, ומה אנחנו רוצים בדיוק לעשות עם הטקסט (עיבוד בזכרון, שליחה לשרות חיצוני, כתיבה לקובץ). 

יום שישי, 28 בדצמבר 2012

מעבר על Properties ו- Methods באובייקט על ידי Reflection

לפעמים נדרש מאיתנו למצוא תכונות ומטודות שונות על אובייקטים בזמן ריצה. הדרך לעשות זאת זה באמצעות Reflection.

לדוגמא:

יש לנו את האובייקט הבא:
 public class Message
    {
        public string Property1 { get; set; }
        public int Property2 { get; set; }

        public Message() 
        {
            Property1 = "Eyal";
            Property2 = 29;
        } 
        
        public void DoSomething()
        {
            //do something
        }
    }

באמצעות הפונקציה הנ"ל, נוכל לקבל כל אובייקט, ובעזרת System.Reflection נוכל לעבור על כל התכונות של האובייקט והפונקציות, ולעשות כרצוננו:

public static void LoopOnPropertiesAndMethods(Object msgcontract)
{
    //Type class is the root class for System.Reflection
    //We are initially creating an object of Type class-
    //which can be used to access the information of an assembly
    Type t = msgcontract.GetType();

    //propertyArray will contain the actual data related to-
    //the object properties
    //If we want to get the non-public properties we should use-
    //t.GetProperties(BindingFlags.NonPublic)
    PropertyInfo[] propertyArray = t.GetProperties();

    foreach (PropertyInfo p in propertyArray)
    {
        //Get the value of the property.
        //for property1 in our example we will recieve "Eyal"
        object propertyValue = p.GetValue(msgcontract, null);

        //Get the propertyName of the property. 
        //for property1 in our example we will recieve "property1"
        string propertyName = p.Name; 
    }

    //methodsArray will contain the actual data related to the object methods
    MethodInfo[] methodsArray = t.GetMethods();

    foreach (MethodInfo m in methodsArray)
    {
        //Get the Method info of the object. 
        //in our example we will recieve "Void doSomething()"
        //(And all the seters and the geters of the properties)
        string name = m.ToString();
    }
}

אפשר להשתמש גם בפונקציות הבאות על Type כדי "לגלות" עוד על האובייקט שקיבלנו:t.IsClass, t.IsAbstract, t.IsPublic ועוד..
עבודה מהנה!