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日

相关文章

  • .net core 3.1 Redis安装和简单使用

    以下是关于“.NET Core 3.1 Redis安装和简单使用”的完整攻略: 1. Redis 简介 Redis 是一种高性能的键值存储数据库,支持多种数据结构如字符串、哈希、列表、集合和有序集合等。 通常用于缓存、会话管理、消息队列和排行榜等场景。 2. Redis 安装 2.1 Windows 安装 在 Windows 上安装 Redis,可以从 Re…

    C# 2023年5月12日
    00
  • 如何在Asp.Net Core中集成Refit

    Asp.Net Core中集成Refit攻略 Refit是一个开源的RESTful API客户端库,它可以帮助我们轻松地使用C#来访问Web API。在Asp.Net Core中,我们可以使用Refit来简化Web API的调用。本攻略将介绍如何在Asp.Net Core中集成Refit。 步骤 以下是在Asp.Net Core中集成Refit的步骤: 安装…

    C# 2023年5月17日
    00
  • C#遍历操作系统下所有驱动器的方法

    1.获得系统下所有驱动器列表 在C#中,我们可以使用DriveInfo类来获取系统下的所有驱动器信息。这个类提供了许多关于驱动器的属性,例如驱动器标签、驱动器类型、驱动器格式和可用空间等等。下面是获取系统下所有驱动器列表的代码示例: using System.IO; //… DriveInfo[] allDrives = DriveInfo.GetDri…

    C# 2023年6月7日
    00
  • C#自定义鼠标拖拽Drag&Drop效果之基本原理及基本实现代码

    C#自定义鼠标拖拽Drag&Drop效果之基本原理 前言 在很多应用程序中,我们都需要使用拖拽效果来实现某些功能,比如拖拽文件到应用程序窗口中打开等。在C#中,我们可以利用Drag&Drop技术自定义鼠标拖拽的效果,本文将会详细讲解Drag&Drop技术的基本原理及基本实现方法。 基本原理 Drag&Drop技术,即拖放技术,…

    C# 2023年6月6日
    00
  • ASP.NET Core的日志系统介绍

    ASP.NET Core 的日志系统介绍 在 ASP.NET Core 中,日志系统是一个非常重要的组件,它可以帮助我们记录应用程序的运行状态和错误信息。本攻略将详细介绍 ASP.NET Core 的日志系统。 日志系统的作用 ASP.NET Core 的日志系统可以帮助我们记录应用程序的运行状态和错误信息,以便我们更好地了解应用程序的运行情况。日志系统可以…

    C# 2023年5月16日
    00
  • C#实现Socket通信的解决方法

    C#实现Socket通信的解决方法,可以分为以下几个步骤: 步骤一:创建Socket对象 首先,需要使用C#提供的System.Net命名空间下的Socket类创建一个Socket对象,可以使用以下代码: using System.Net; using System.Net.Sockets; Socket socket = new Socket(Addres…

    C# 2023年6月1日
    00
  • C#如何实现图片的剪裁并保存

    下面是C#实现图片剪裁并保存的攻略,包含两个示例说明。 1.准备工作 在开始实现图片剪裁之前,需要先引用System.Drawing命名空间,该命名空间是提供处理图片的基本类。 在引用之前需要确保本地已安装.NET Framework SDK,如果未安装可在微软官网下载并安装。 如下所示: using System.Drawing; 其次,需要了解图片剪裁需…

    C# 2023年6月6日
    00
  • ASP.NET Core 2.0 WebApi全局配置及日志实例

    ASP.NET Core 2.0 WebApi全局配置及日志实例 在 ASP.NET Core 2.0 WebApi 中,可以使用全局配置和日志来提高应用程序的可维护性和可扩展性。以下是 ASP.NET Core 2.0 WebApi 全局配置及日志实例的完整攻略: 步骤一:全局配置 在 ASP.NET Core 2.0 WebApi 中,可以使用 apps…

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