导读:本期聚焦于小伙伴创作的《C#中dynamic动态对象如何实现方法和属性的动态调用》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#中dynamic动态对象如何实现方法和属性的动态调用》有用,将其分享出去将是对创作者最好的鼓励。

C#的dynamic类型允许我们在编译阶段跳过类型检查,将类型解析的工作推迟到运行时完成,这为动态实现方法和属性的调用提供了便利。我们可以通过自定义动态对象,灵活扩展方法和属性的动态操作能力,适配多变的业务场景。

C#中dynamic动态对象如何实现方法和属性的动态调用

dynamic类型基础特性

dynamic类型是C# 4.0引入的静态类型,它在编译时会被标记为dynamic,编译器不会对其成员访问做静态类型检查,所有类型检查会在运行时由DLR(动态语言运行时)完成。它和object类型的最大区别在于,object类型的成员调用需要显式类型转换,而dynamic类型可以直接调用成员,不需要提前知道对象的具体类型。

下面是一段基础的dynamic类型使用示例:

using System;

class Program
{
    static void Main()
    {
        // 定义dynamic类型变量
        dynamic dynamicValue = 10;
        Console.WriteLine(dynamicValue); // 输出10
        
        // 动态修改变量类型,不需要显式转换
        dynamicValue = "hello dynamic";
        Console.WriteLine(dynamicValue.Length); // 输出13,运行时解析Length属性
    }
}

自定义动态对象实现动态属性

要实现自定义的方法和属性动态调用,需要继承DynamicObject类,并重写对应的虚方法。首先我们来看动态属性的实现,需要重写TryGetMemberTrySetMember方法,这两个方法分别处理属性的读取和赋值操作。

下面是一个支持动态属性的自定义动态对象实现:

using System;
using System.Collections.Generic;
using System.Dynamic;

public class DynamicPropertyObject : DynamicObject
{
    // 存储动态属性的字典
    private Dictionary<string, object> _properties = new Dictionary<string, object>();

    // 重写属性读取方法
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        // 检查属性是否存在
        if (_properties.ContainsKey(binder.Name))
        {
            result = _properties[binder.Name];
            return true;
        }
        // 属性不存在时返回null
        result = null;
        return true;
    }

    // 重写属性赋值方法
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        // 存储属性值
        _properties[binder.Name] = value;
        return true;
    }
}

使用这个动态对象时,我们可以随意添加和访问属性,不需要提前定义:

using System;

class Program
{
    static void Main()
    {
        dynamic obj = new DynamicPropertyObject();
        // 动态设置属性,不需要提前定义Name和Age属性
        obj.Name = "张三";
        obj.Age = 25;
        obj.IsStudent = true;

        // 动态读取属性
        Console.WriteLine($"姓名:{obj.Name}"); // 输出 姓名:张三
        Console.WriteLine($"年龄:{obj.Age}"); // 输出 年龄:25
        Console.WriteLine($"是否学生:{obj.IsStudent}"); // 输出 是否学生:True
    }
}

自定义动态对象实现动态方法

实现动态方法需要重写TryInvokeMember方法,这个方法会在调用动态对象的方法时触发,我们可以在这个方法内部自定义方法的处理逻辑,比如根据方法名动态执行不同的操作。

下面是支持动态方法的自定义动态对象实现:

using System;
using System.Dynamic;
using System.Reflection;

public class DynamicMethodObject : DynamicObject
{
    // 重写方法调用逻辑
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        string methodName = binder.Name;
        // 根据方法名执行不同逻辑
        switch (methodName)
        {
            case "Add":
                // 处理Add方法,假设参数是两个数字
                if (args.Length == 2 && args[0] is int a && args[1] is int b)
                {
                    result = a + b;
                    return true;
                }
                break;
            case "Concat":
                // 处理Concat方法,假设参数是两个字符串
                if (args.Length == 2 && args[0] is string s1 && args[1] is string s2)
                {
                    result = s1 + s2;
                    return true;
                }
                break;
            default:
                // 未知方法抛出异常
                throw new MissingMethodException($"不支持的方法:{methodName}");
        }
        result = null;
        return false;
    }
}

使用这个动态对象调用动态方法:

using System;

class Program
{
    static void Main()
    {
        dynamic obj = new DynamicMethodObject();
        // 调用动态Add方法
        int sum = obj.Add(3, 5);
        Console.WriteLine($"3+5的结果:{sum}"); // 输出 3+5的结果:8

        // 调用动态Concat方法
        string concatResult = obj.Concat("Hello ", "World");
        Console.WriteLine($"拼接结果:{concatResult}"); // 输出 拼接结果:Hello World

        // 调用不存在的方法会抛出异常
        try
        {
            obj.Multiply(2, 3);
        }
        catch (MissingMethodException ex)
        {
            Console.WriteLine(ex.Message); // 输出 不支持的方法:Multiply
        }
    }
}

同时支持动态属性和方法的动态对象

我们可以将前面的属性处理逻辑和方法处理逻辑结合,实现一个同时支持动态属性和动态方法的完整动态对象:

using System;
using System.Collections.Generic;
using System.Dynamic;

public class FullDynamicObject : DynamicObject
{
    private Dictionary<string, object> _properties = new Dictionary<string, object>();

    // 动态属性读取
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (_properties.ContainsKey(binder.Name))
        {
            result = _properties[binder.Name];
            return true;
        }
        result = null;
        return true;
    }

    // 动态属性赋值
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _properties[binder.Name] = value;
        return true;
    }

    // 动态方法调用
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        string methodName = binder.Name;
        if (methodName == "PrintAllProperties")
        {
            // 打印所有动态属性
            foreach (var kv in _properties)
            {
                Console.WriteLine($"{kv.Key}: {kv.Value}");
            }
            result = null;
            return true;
        }
        result = null;
        return false;
    }
}

使用示例:

using System;

class Program
{
    static void Main()
    {
        dynamic obj = new FullDynamicObject();
        // 设置动态属性
        obj.Id = 1001;
        obj.UserName = "李四";
        obj.Score = 95.5;

        // 调用动态方法
        obj.PrintAllProperties();
        // 输出:
        // Id: 1001
        // UserName: 李四
        // Score: 95.5
    }
}

dynamic动态对象使用注意事项

  • dynamic类型的调用是在运行时解析的,如果调用的成员不存在,会在运行时抛出RuntimeBinderException,所以需要确保调用的成员在运行时是真实存在的。
  • dynamic类型的性能比静态类型稍差,因为运行时需要额外的类型解析开销,不适合在高频调用的核心逻辑中大量使用。
  • dynamic类型无法享受编译器的智能提示和类型检查,代码编写阶段不容易发现拼写错误等问题,需要额外做好测试。
  • dynamic类型不能用于匿名方法、Lambda表达式的参数类型声明,也不能作为扩展方法的第一个参数类型。

C#dynamic动态对象方法调用属性调用修改时间:2026-06-04 15:14:38

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。