Merhaba,

Bir projemde kullanmak üzere yazdığım sınıfı paylaşmak istiyorum. Bu sınıf, PHP'de bulunan "serialize" ve "unserialize" fonksiyonlarının C# halleri yer almaktadır.

Referanslar;

using System.Collections;
using System.Globalization;
Sınıfın kodları;

    public class Serializer
    {
        private readonly NumberFormatInfo _NumberFormatInfo;

        private Encoding _Encoding = new UTF8Encoding();

        private bool _SafeXml = true;

        private int _Position;

        private Dictionary<ArrayList, bool> _SeenArrayLists;

        private Dictionary<Hashtable, bool> _SeenHashtables;

        public Serializer()
        {
            _NumberFormatInfo = new NumberFormatInfo();

            _NumberFormatInfo.NumberDecimalSeparator = ".";

            _NumberFormatInfo.NumberGroupSeparator = "";
        }

        public string Serialize(dynamic Object)
        {
            _SeenArrayLists = new Dictionary<ArrayList, bool>();

            _SeenHashtables = new Dictionary<Hashtable, bool>();

            return _Serialize(Object, new StringBuilder()).ToString();
        }

        public dynamic Unserialize(string String)
        {
            _Position = 0;

            return _Unserialize(String);
        }

        private StringBuilder _Serialize(dynamic Object, StringBuilder StringBuilder)
        {
            if (Object == null)
            {
                return StringBuilder.Append("N;");
            }

            if (Object is string)
            {
                var String = (string) Object;

                if (_SafeXml)
                {
                    String = String.Replace("\r\n", "\n");

                    String = String.Replace("\r", "\n");
                }

                return StringBuilder.Append("s:" + _Encoding.GetByteCount(String) + ":\"" + String + "\";");
            }

            if (Object is bool)
            {
                return StringBuilder.Append("b:" + (((bool) Object) ? "1" : "0") + ";");
            }

            if (Object is int)
            {
                var Integer = (int) Object;

                return StringBuilder.Append("i:" + Integer.ToString(_NumberFormatInfo) + ";");
            }

            if (Object is double)
            {
                var Double = (double) Object;

                return StringBuilder.Append("d:" + Double.ToString(_NumberFormatInfo) + ";");
            }

            if (Object is ArrayList)
            {
                if (_SeenArrayLists.ContainsKey((ArrayList) Object))
                {
                    return StringBuilder.Append("N;");
                }

                _SeenArrayLists.Add((ArrayList) Object, true);

                var ArrayList = (ArrayList) Object;

                StringBuilder.Append("a:" + ArrayList.Count + ":{");

                for (int Index = 0; Index < ArrayList.Count; Index++)
                {
                    _Serialize(Index, StringBuilder);
                    _Serialize(ArrayList[Index], StringBuilder);
                }

                StringBuilder.Append("}");

                return StringBuilder;
            }

            if (Object is Hashtable)
            {
                if (_SeenHashtables.ContainsKey((Hashtable) Object))
                {
                    return StringBuilder.Append("N;");
                }

                _SeenHashtables.Add((Hashtable) Object, true);

                var HashtableObject = (Hashtable) Object;

                StringBuilder.Append("a:" + HashtableObject.Count + ":{");

                foreach (DictionaryEntry Entry in HashtableObject)
                {
                    _Serialize(Entry.Key, StringBuilder);
                    _Serialize(Entry.Value, StringBuilder);
                }

                StringBuilder.Append("}");

                return StringBuilder;
            }

            return StringBuilder;
        }

        private dynamic _Unserialize(string String)
        {
            if (String == null || String.Length <= _Position)
            {
                return new Object();
            }

            int StartPosition, EndPosition, Length;

            string StringLength;

            switch (String[_Position])
            {
                case 'N':
                    _Position += 2;

                    return null;
                case 'b':
                    char CharBool = String[_Position + 2];

                    _Position += 4;

                    return CharBool == '1';
                case 'i':
                    StartPosition = String.IndexOf(":", _Position, StringComparison.Ordinal) + 1;

                    EndPosition = String.IndexOf(";", StartPosition, StringComparison.Ordinal);

                    string StringInteger = String.Substring(StartPosition, EndPosition - StartPosition);

                    _Position += 3 + StringInteger.Length;

                    return Int32.Parse(StringInteger, _NumberFormatInfo);
                case 'd':
                    StartPosition = String.IndexOf(":", _Position, StringComparison.Ordinal) + 1;

                    EndPosition = String.IndexOf(";", StartPosition, StringComparison.Ordinal);

                    string StringDouble = String.Substring(StartPosition, EndPosition - StartPosition);

                    _Position += 3 + StringDouble.Length;

                    return Int32.Parse(StringDouble, _NumberFormatInfo);
                case 's':
                    StartPosition = String.IndexOf(":", _Position, StringComparison.Ordinal) + 1;

                    EndPosition = String.IndexOf(":", StartPosition, StringComparison.Ordinal);

                    StringLength = String.Substring(StartPosition, EndPosition - StartPosition);

                    int ByteLength = Int32.Parse(StringLength);

                    Length = ByteLength;

                    if ((EndPosition + 2 + Length) >= String.Length)
                    {
                        Length = String.Length - 2 - EndPosition;
                    }

                    string StringString = String.Substring(EndPosition + 2, Length);

                    while (_Encoding.GetByteCount(StringString) > ByteLength)
                    {
                        Length--;

                        StringString = String.Substring(EndPosition + 2, Length);
                    }

                    _Position += 6 + StringLength.Length + Length;

                    if (_SafeXml)
                    {
                        StringString = StringString.Replace("\n", "\r\n");
                    }

                    return StringString;
                case 'a':
                    StartPosition = String.IndexOf(":", _Position, StringComparison.Ordinal) + 1;

                    EndPosition = String.IndexOf(":", StartPosition, StringComparison.Ordinal);

                    StringLength = String.Substring(StartPosition, EndPosition - StartPosition);

                    Length = Int32.Parse(StringLength);

                    var StringHashtable = new Hashtable(Length);

                    var StringArrayList = new ArrayList(Length);

                    _Position += 4 + StringLength.Length;

                    for (int Index = 0; Index < Length; Index++)
                    {
                        object Key = _Unserialize(String);

                        object Value = _Unserialize(String);

                        if (StringArrayList != null)
                        {
                            if (Key is int && (int) Key == StringArrayList.Count)
                            {
                                StringArrayList.Add(Value);
                            }
                            else
                            {
                                StringArrayList = null;
                            }
                        }

                        StringHashtable[Key] = Value;
                    }

                    _Position++;

                    if (_Position < String.Length && String[_Position] == ';')
                    {
                        _Position++;
                    }

                    if (StringArrayList != null)
                    {
                        return StringArrayList;
                    }

                    return StringHashtable;
                default:
                    return "";
            }
        }
    }
Sınıfın desteklediği veri türleri;
  • array (Hashtable)
  • boolean
  • double
  • string
  • integer

Sınıfın kullanımı;

            /*
                <?php
             
                    header('Content-Type: text/plain; charset=UTF-8');
                    
                    $users = array(
                        array(
	                		'id' => 1
		                ),
		                array(
			                'id' => 2
		                )
	                );

	                echo serialize($users);
                 ?>
             */
            string SerializedTestData = "a:2:{i:0;a:1:{s:2:\"id\";i:1;}i:1;a:1:{s:2:\"id\";i:2;}}";

            Serializer Serializer = new Serializer();

            dynamic UnserializedTestData = Serializer.Unserialize(SerializedTestData);

            foreach (dynamic Item in UnserializedTestData)
            {
                Console.WriteLine("Item: " + Item["id"]);
            }

            Console.ReadKey();
Çıktı;