C#自定义实现Json字符串向对象转换:基于反射与特性映射

陆遥
陆遥
发布时间:2026-10-14| 6人浏览过
原创

本文将详细介绍如何在C#环境中,通过自定义Attribute结合反射技术,将简单的JSON字符串转换为特定的C#对象实例。该方法避免了引入大型序列化库的开销,适合处理结构简单、格式固定的JSON数据。

设计思路与准备条件

目标:将形如{"key":"value", "id":123}格式的JSON字符串解析为C#类实例。
核心原理:

  • 使用[JsonField]自定义特性标记类属性,指定其对应的JSON键名。
  • 利用反射获取类的公共属性及对应的特性信息。
  • 通过简单的字符串分割提取JSON中的键值对(注意:此方法仅适用于简单的扁平结构)。
  • 使用泛型Type.Parse方法进行类型转换赋值。

第一步:定义映射特性

首先需要创建一个继承自Attribute的特性类,用于标识C#属性与JSON字段名称的对应关系。

代码如下:
namespace JsonMapper
{
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
    public class JsonFieldAttribute : Attribute
    {
        private string _Name = string.Empty;

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
    }
}

第二步:实现核心转换器

创建JsonToInstance类,实现从JSON字符串到任意类型的转换。核心在于解析逻辑和类型匹配。

代码如下:
namespace JsonMapper
{
    public class JsonToInstance
    {
        /// 
        /// 将JSON字符串转换为指定类型的对象
        /// 
        public T ToInstance<T>(string json) where T : new()
        {
            // 1. 简单解析JSON为字典 (注意:此方法仅支持最简JSON结构)
            Dictionary<string, string> dic = new Dictionary<string, string>();
            
            // 去除首尾花括号(如有)并根据逗号分割键值对
            string content = json.Trim().Trim('{', '}');
            string[] fields = content.Split(',');
            
            for (int i = 0; i < fields.Length; i++)
            {
                string[] keyvalue = fields[i].Split(':');
                if (keyvalue.Length == 2)
                {
                    dic.Add(Filter(keyvalue[0]), Filter(keyvalue[1]));
                }
            }

            // 2. 获取所有公共实例属性
            PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            T entity = new T();

            // 3. 遍历属性并赋值
            foreach (PropertyInfo property in properties)
            {
                object[] propertyAttrs = property.GetCustomAttributes(false);
                foreach (object propertyAttr in propertyAttrs)
                {
                    if (propertyAttr is JsonFieldAttribute jsonFieldAttribute)
                    {
                        // 查找匹配的键
                        foreach (KeyValuePair<string, string> item in dic)
                        {
                            if (item.Key == jsonFieldAttribute.Name)
                            {
                                Type t = property.PropertyType;
                                // 进行类型转换
                                property.SetValue(entity, ToType(t, item.Value), null);
                                break;
                            }
                        }
                        break;
                    }
                }
            }

            return entity;
        }

        /// 
        /// 过滤JSON字符串中的引号
        /// 
        private string Filter(string str)
        {
            if (!str.StartsWith("\"") || !str.EndsWith("\""))
            {
                return str.Trim();
            }
            else
            {
                return str.Substring(1, str.Length - 2);
            }
        }

        /// 
        /// 根据类型将字符串转换为对应对象
        /// 
        public object ToType(Type type, string value)
        {
            // 如果是字符串直接返回
            if (type == typeof(string))
            {
                return value;
            }

            // 尝试查找静态Parse方法
            MethodInfo parseMethod = null;
            foreach (MethodInfo mi in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
            {
                if (mi.Name == "Parse" && mi.GetParameters().Length == 1)
                {
                    parseMethod = mi;
                    break;
                }
            }

            if (parseMethod == null)
            {
                throw new ArgumentException($"Type: {type.Name} does not have a valid Parse method!");
            }

            // 调用Parse方法
            return parseMethod.Invoke(null, new object[] { value });
        }
    }
}

第三步:定义业务模型

创建需要使用此转换器的C#类,并使用[JsonField]标记每个属性。

代码如下:
// JSON样例: { "result": 100, "response": "Hello", "id": 123, "msg": "OK." }
public class Message
{
    [JsonField(Name = "result")]
    public int Result { get; set; }

    [JsonField(Name = "response")]
    public string Response { get; set; }

    [JsonField(Name = "id")]
    public int Id { get; set; }

    [JsonField(Name = "msg")]
    public string Msg { get; set; }
}

第四步:测试与运行

在主程序中调用转换器,验证结果是否符合预期。

代码如下:
class Program
{
    static void Main(string[] args)
    {
        JsonToInstance util = new JsonToInstance();
        // 注意:输入应为标准的JSON字符串格式
        string json = @"{""response"":""我是阿猫酱的小黄鸡"",""id"":21231513,""result"":100,""msg"":""OK.""}";
        
        try 
        {
            Message m = util.ToInstance<Message>(json);
            Console.WriteLine($"ID: {m.Id}, Msg: {m.Msg}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}

局限性与注意事项

  • 解析方式简易:上述代码使用Split(',')进行分割,这意味着它不支持嵌套JSON或数组类型的字段,也不处理JSON注释。 对于复杂的JSON结构,建议使用成熟的库如Newtonsoft.Json或System.Text.Json。
  • 类型限制:目前仅支持具有静态Parse(string)方法的类型(如int, double, DateTime等)。如果需要支持自定义复杂类型,需扩展ToType方法。
  • 性能考量:由于大量使用了反射,此方法的执行效率低于原生序列化库。它更适合低频调用或轻量级场景。

以上就是C#自定义实现Json字符串向C#对象转变的详细内容,更多关于C# Json转换的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。