C# Dynamic之:ExpandoObject,DynamicObject,DynamicMetaOb的应用(上)

那我开始讲解C# Dynamic之:ExpandoObject,DynamicObject,DynamicMetaObject的应用(上)的完整攻略。

1. 概述

首先,需要了解什么是动态类型,以及为什么需要使用动态类型。在C#中,变量的类型实际上是由编译器推断出来的,也就是静态类型。而动态类型是指在运行时才确定类型的类型。动态类型的主要作用是在不确定类型时,可以通过运行时信息来确定类型,从而实现更灵活的编程。

在C#中,提供了一些机制来支持动态类型,其中ExpandoObject、DynamicObject和DynamicMetaObject是比较常见的。

2. ExpandoObject

ExpandoObject是一种可以动态添加属性和方法的对象。通过ExpandoObject,可以在运行时动态添加属性和方法,而不需要在编译时就确定属性和方法。下面是一个使用ExpandoObject的示例:

dynamic person = new ExpandoObject();
person.Name = "John";
person.Age = 30;
person.SayHello = (Action)(() => Console.WriteLine("Hello, my name is " + person.Name));
person.SayHello();

在上面的示例中,我们创建了一个ExpandoObject对象,并且动态的添加了Name、Age属性和SayHello方法。通过这种方式,我们可以灵活的定义对象的属性和方法,并在运行时动态的添加和使用它们。

3. DynamicObject

DynamicObject是一个可以重写成员访问的类。通过继承DynamicObject,可以动态定义对象的成员访问行为。下面是一个使用DynamicObject的示例:

class MyDynamicClass : DynamicObject
{
    private readonly Dictionary<string, object> _dictionary = 
        new Dictionary<string, object>();

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        string name = binder.Name.ToLower();
        return _dictionary.TryGetValue(name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _dictionary[binder.Name.ToLower()] = value;
        return true;
    }
}

dynamic obj = new MyDynamicClass();
obj.Name = "John";
Console.WriteLine(obj.Name);

在上面的示例中,我们自定义了一个MyDynamicClass类,该类继承自DynamicObject并重载了TryGetMember和TrySetMember方法。在TryGetMember和TrySetMember方法中,我们实现了访问对象成员的方式,例如可以将对象的属性名称转化为小写后在Dictionary中查找对应的值。

4. DynamicMetaObject

DynamicMetaObject是一个提供动态行为元数据的类。通过重载DynamicMetaObject,可以实现更高级的动态类型行为。下面是一个使用DynamicMetaObject的示例:

class MyDynamicClass : DynamicObject
{
    private readonly Dictionary<string, object> _dictionary =
        new Dictionary<string, object>();

    public override DynamicMetaObject GetMetaObject(Expression parameter)
    {
        return new MyDynamicMetaObject(parameter, this);
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        string name = binder.Name.ToLower();
        return _dictionary.TryGetValue(name, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        _dictionary[binder.Name.ToLower()] = value;
        return true;
    }
}

class MyDynamicMetaObject : DynamicMetaObject
{
    public MyDynamicMetaObject(Expression expression, object value)
        : base(expression, BindingRestrictions.Empty, value)
    {
    }

    public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
    {
        var name = Expression.Constant(binder.Name.ToLower());
        var dictionary = Expression.Property(Expression.Constant(Value), "Dictionary");
        var index = Expression.Call(dictionary, "TryGetValue", null, name,
            Expression.Variable(typeof(object)));
        var restriction = BindingRestrictions.GetTypeRestriction(Expression, LimitType);
        var value = Expression.Variable(typeof(object));

        var fallback = Expression.Block(
            Expression.Assign(value, Expression.Default(typeof(object))),
            Expression.Convert(value, binder.ReturnType));

        var binding = new DynamicMetaObject(
            Expression.Block(
                new[] { value },
                Expression.Condition(index, Expression.Convert(Expression.Property(
                                                Expression.Variable(value),
                                                "Value"),
                                                binder.ReturnType),
                                      fallback)),
            restriction,
            this);

        return binding;
    }
}

dynamic obj = new MyDynamicClass();
obj.Name = "John";
Console.WriteLine(obj.Name);

在上面的示例中,我们自定义了一个MyDynamicClass类,该类继承自DynamicObject并重载了GetMetaObject、TryGetMember和TrySetMember方法。在GetMetaObject方法中,我们返回了一个MyDynamicMetaObject实例,该实例提供了我们需要实现的动态行为元数据。

在MyDynamicMetaObject类中,我们重载了BindGetMember方法,该方法定义了用于动态访问成员的逻辑。这里我们使用Expression来实现了一个动态的条件语句,该条件语句尝试从Dictionary中读取属性值,如果成功则返回对应的值,否则返回默认值。

5. 总结

以上就是对于C# Dynamic之:ExpandoObject,DynamicObject,DynamicMetaObject的应用(上)的完整攻略。ExpandoObject、DynamicObject和DynamicMetaObject都是C#中实现动态类型的重要机制,使用它们可以带来更灵活的编程体验,使编程更加便捷。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# Dynamic之:ExpandoObject,DynamicObject,DynamicMetaOb的应用(上) - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • 使用C#创建Windows服务的实例代码

    下面我将为你分享如何使用C#创建Windows服务的攻略,步骤包含两条示例说明。 一、创建Windows服务 1.打开Visual Studio,在菜单中选择“文件”→“新建”→“项目”→“Windows服务”。 2.设置服务名称和解决方案名称等信息,点击“创建”按钮。 3.在“Solution Explorer”中找到“Service1.cs”文件,并双击…

    C# 2023年6月3日
    00
  • 一文带你吃透C#中面向对象的相关知识

    一文带你吃透C#中面向对象的相关知识 什么是面向对象 面向对象编程是一种编程方法和思想,它的核心是将事物抽象为对象,并通过对象之间的交互来完成任务。在C#中,一切皆为对象,包括类和结构体等用户定义的类型,以及基本类型如int,float等。 类与对象 类是创建对象的模板,它定义了对象的属性和方法。对象是类的实例,它是内存中分配的一块区域,可以存储类的属性值。…

    C# 2023年5月14日
    00
  • C#集合之有序列表的用法

    我会给出一份详细的C#集合之有序列表的用法的攻略。 什么是有序列表? 在C#中,有序列表是一种类型的集合,其元素以特定的次序进行排序并储存。有序列表通常包括两种形式,分别为数组(Array)和列表(List),而我们今天要介绍的是列表的使用方法。 使用有序列表可以解决许多常见问题,如按照特定标准对集合进行排序和顺序查找等。同时,列表也支持插入、删除和更新元素…

    C# 2023年5月15日
    00
  • python简单线程和协程学习心得(分享)

    Python简单线程和协程学习心得 线程和协程的区别 线程是操作系统的调度单位,是由操作系统来进行线程调度,每个线程拥有自己的内存空间,一个线程会包含多个任务的处理过程,可以实现同时执行多个任务的效果。 而协程则是在用户程序中自行切换的,每个协程之间并不存在系统线程之间的上下文切换开销,协程是一种轻量级的线程,可以在同一个线程中运行,不会让操作系统进行线程上…

    C# 2023年6月6日
    00
  • C#.NET 图片水印添加代码

    下面是 “C#.NET 图片水印添加代码” 的详细攻略。 一、准备工作 了解 C# 语言和 .NET 框架 安装 Visual Studio 开发环境,并选择 C# 开发环境 安装开源图片处理库 ImageProcessor 二、添加水印的基本步骤 加载要添加水印的图片 定义水印文字或水印图片 在图片上绘制水印 保存新的图片 三、示例代码说明 示例一:添加文…

    C# 2023年5月31日
    00
  • C#编程总结(一)序列化总结

    下面是关于“C#编程总结(一)序列化总结”的完整攻略,包含两个示例。 1. 序列化总结 在C#编程中,序列化是将对象转换为可存储或可传输格式的过程。反序列化是将序列化的数据转换回对象的过程。C#提供了多种序列化方式,包括二进制序列化、XML序列化和JSON序列化等。以下是C#编程中序列化的总结: 1.1 二进制序列化 二进制序列化是将对象转换为二进制格式的过…

    C# 2023年5月15日
    00
  • unity实现弧形移动 可角度自定

    Unity实现弧形移动 可角度自定攻略 介绍 在Unity游戏开发中,经常需要实现物体从一个点移动到另一个点,而不是沿着直线运动。本文将介绍如何使用Unity实现弧形运动,并且可设定运动角度的完整攻略。 实现过程 以下是设定弧形移动的步骤: 步骤一:准备工作 在Unity中,需要先创建一个空物体Empty,将需要弧形运动的物体作为Empty的子物体,然后将所…

    C# 2023年6月3日
    00
  • C#3.0使用EventLog类写Windows事件日志的方法

    关于如何使用 C#3.0 的 EventLog 类写 Windows 事件日志,我们可以按照以下步骤进行: 1. 引用 System.Diagnostics 命名空间 在 C#3.0 中,我们需要使用 System.Diagnostics 命名空间提供的 EventLog 类来访问 Windows 事件日志。因此,在代码文件的头部,需要使用 using 指令…

    C# 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部