原 ObjectToJson实现

特性标记:

    [System.AttributeUsage(System.AttributeTargets.Property)]
    class UseForJsonAttribute : Attribute
    {
        public Boolean IsUse { get; set; }
        public UseForJsonAttribute(Boolean isUse)
        {
            IsUse = isUse;
        }
    }

代码:

    public class ObjToJson<T>
    {
        //为null时返回
        private const string undifined = "\"undefined\"";
        StringBuilder jsonBuilder = new StringBuilder();
        public ObjToJson()
        {
            if (typeof(T).IsGenericType)
            { throw new Exception("暂不支持泛型"); }
        }
        public string ToJson(T instance)
        {
            if (instance == null) return undifined;
            MakeJson(instance);
            return jsonBuilder.ToString();
        }
        private void MakeJson(Object instance)
        {
            //区分数组类型和普通类
            if (instance is Array)
            {
                ArrayToJson(instance);
            }
            else {
                EntityToJson(instance);
            }
        }
        private void ArrayToJson(Object instance)
        {
            jsonBuilder.Append("[");
            Array obj = (instance as Array);
            //逐个循环调用makjson
            for (int i = 0; i < obj.Length; i++)
            {
                if (obj.GetValue(i) == null)
                    jsonBuilder.Append(undifined);
                else
                    MakeJson(obj.GetValue(i));
                jsonBuilder.Append(",");
            }
            if (jsonBuilder[jsonBuilder.Length - 1] == ',')
            {
                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            }
            jsonBuilder.Append("]");
        }
        private void EntityToJson(Object instance)
        {
            jsonBuilder.Append("{");
            PropertyInfo[] pInfos = instance.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
            foreach (PropertyInfo pInfo in pInfos)
            {
                //判断该成员是否序列
                if (IsUseProperty(pInfo))
                {
                    //加入key
                    jsonBuilder.Append("\"");
                    TransformChar(pInfo.Name);
                    jsonBuilder.Append("\":");
                    //加入value
                    object value = pInfo.GetValue(instance);
                    if (pInfo.PropertyType.IsValueType)
                    {
                        //值类型
                        TransformChar(value.ToString());
                        jsonBuilder.Append(',');
                    }            
                    else if (pInfo.PropertyType.ToString() == "System.String")
                    {
                        //字符类型
                        jsonBuilder.Append("\"");
                        if (value == null)
                            jsonBuilder.Append(undifined);
                        else
                            TransformChar(value.ToString());
                        jsonBuilder.Append("\",");
                    }
                    else {
                        //引用类型
                        if (value == null)
                            jsonBuilder.Append(undifined);
                        else
                            MakeJson(value);
                        jsonBuilder.Append(',');
                    }
                }
            }
            if (jsonBuilder[jsonBuilder.Length - 1] == ',')
            {
                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            }
            jsonBuilder.Append("}");
        }
        private bool IsUseProperty(PropertyInfo pInfo)
        {
            UseForJsonAttribute ufa = pInfo.GetCustomAttribute<UseForJsonAttribute>();
            if (ufa != null && ufa.IsUse == true)
            { return true; }
            return false;
        }
        private void TransformChar(string aString)
        {
            for (int i = 0; i < aString.Length; ++i)
            {
                switch (aString[i])
                {
                    case '\\':
                        jsonBuilder.Append("\\\\");
                        break;

                    case '/':
                        jsonBuilder.Append("\\/");
                        break;

                    case '"':
                        jsonBuilder.Append("\\\"");
                        break;

                    case '\t':
                        jsonBuilder.Append("\\t");
                        break;
                    case '\f':
                        jsonBuilder.Append("\\f");
                        break;
                    case '\b':
                        jsonBuilder.Append("\\b");
                        break;
                    case '\n':
                        jsonBuilder.Append("\\n");
                        break;
                    case '\r':
                        jsonBuilder.Append("\\r");
                        break;
                    default:
                        {
                            jsonBuilder.Append(aString[i]);
                            break;
                        }

                }
            }
        }
    }

测试类:

    public class Class
    {
        [UseForJsonAttribute(true)]
        public int RoomID { get; set; }
        [UseForJsonAttribute(true)]
        public string description { get; set; }
        [UseForJsonAttribute(true)]
        public Person[] students { get; set; }
        [UseForJsonAttribute(true)]
        public Person teacher { get; set; }
    }
    public class Person
    {
        public Person() { }
        [UseForJsonAttribute(true)]
        public String Name { get; set; }
        [UseForJsonAttribute(true)]
        public Address Address { get; set; }
        [UseForJsonAttribute(true)]
        public int Age { get; set; }
    }
public class Address {
        [UseForJsonAttribute(true)]
        public string Country { get; set; }
        [UseForJsonAttribute(true)]
        public string Privince { get; set; }

        public int Num { get; set; }
}

json生成测试

 Address address1 = new Address();
            address1.Country = "china";
            address1.Privince = "shanghai";

            Address address2 = new Address();
            address2.Country = "china";
            address2.Privince = "beijjing";

            Address address3 = new Address();
            address3.Country = "china";
            address3.Privince = "anhui";

            Person person1 = new Person();
            person1.Name = "jake";
            person1.Age = 22;
            person1.Address = address1;

            Person person2 = new Person();
            person2.Name = "jake";
            person2.Age = 22;
            person2.Address = address1;

            Person person3 = new Person();
            person3.Name = "jake";
            person3.Age = 22;
            person3.Address = address1;

            Class class1 = new Class();
            class1.RoomID = 12;
            class1.teacher = person1;

            class1.students = new Person[5];
            class1.students[0] = person2;
            class1.students[1] = null;
            class1.students[2] = person3;
            class1.students[3] = null;
            class1.students[4] = person3;
            class1.description = "\\\'\".,sadwqqw\t\req\\we\n{}[]";
            ObjToJson<Class> json = new ObjToJson<Class>();
            this.textBox1.Text = json.ToJson(class1);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏blackheart的专栏

[C#3] 1-扩展方法

1.从DEMO开始 先看一个扩展方法的例子: 1 class Program 2 { 3 public static void Main(...

21310
来自专栏博客园

Object.assign()

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects...

1612
来自专栏mukekeheart的iOS之旅

No.014 Longest Common Prefix

14. Longest Common Prefix Total Accepted: 112204 Total Submissions: 385070 Diffi...

2296
来自专栏积累沉淀

Spark 算子

RDD算子分类,大致可以分为两类,即: Transformation:转换算子,这类转换并不触发提交作业,完成作业中间过程处理。 Action:行动算子,这类算...

2285
来自专栏待你如初见

对象序列化与反序列化

851
来自专栏Coding迪斯尼

java开发编译器:把C语言的循环指令编译成java字节码

1713
来自专栏cmazxiaoma的架构师之路

Java数据结构和算法(2)--《Java数据结构和算法》第二版 Robert lafore第二章【数组】编码作业

2033
来自专栏一个会写诗的程序员的博客

《Kotlin 程序设计》第四章 Kotlin 语法基础

Kotlin 可以省略变量定义的类型声明,但是在定义参数列表和定义返回值类型时则必须明确指定类型(这个类型推断Kotlin居然没做,这地方用起来比Scala,G...

962
来自专栏xingoo, 一个梦想做发明家的程序员

[大数据之Spark]——Transformations转换入门经典实例

Spark相比于Mapreduce的一大优势就是提供了很多的方法,可以直接使用;另一个优势就是执行速度快,这要得益于DAG的调度,想要理解这个调度规则,还要理...

2105
来自专栏机器学习入门

LWC 63:748. Shortest Completing Word

LWC 63:748. Shortest Completing Word 传送门:748. Shortest Completing Word Problem: ...

2069

扫码关注云+社区