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日

相关文章

  • JQuery打造PHP的AJAX表单提交实例

    以下是“JQuery打造PHP的AJAX表单提交实例”的完整攻略,包括什么是AJAX表单提交、如何使用JQuery实现AJAX表单提交以及两个示例。 什么是AJAX表单提交? AJAX表单提交是指使用AJAX技术将表单数据提交到服务器,而无需刷新整个页面。AJAX表单提交可以提高用户体验,减少页面刷新次数,提高网站性能。 以下是使用AJAX技术提交表单的示例…

    C# 2023年5月15日
    00
  • linq中的转换操作符

    当我们需要对一个或多个集合进行筛选、排序、分组等操作时,Linq提供了一些转换操作符(也称为方法)来处理数据,例如Where、OrderBy、GroupBy等。以下是Linq中的转换操作符的详细攻略。 1. Where Where方法可以用于过滤出符合条件的元素。该方法的参数是返回布尔值的Lambda表达式,表示元素是否符合条件。可以通过使用链式编程(cha…

    C# 2023年6月1日
    00
  • c#中利用Tu Share获取股票交易信息

    下面是关于“c#中利用Tu Share获取股票交易信息”的完整攻略。 一、概述 Tu Share是一个免费提供A股、港股等股票交易数据的API,其提供了多种语言的接口,包括Python、Java、C#等,本攻略将介绍如何在C#中使用Tu Share获取股票交易信息。 二、注册账号 在使用Tu Share API之前,需要先注册一个账号,具体如下所示:1. 打…

    C# 2023年5月31日
    00
  • C#隐式/显示实现接口方法详解

    C#隐式/显示实现接口方法详解 在 C# 中,接口是构建松散耦合系统的一种有用的机制。类可以继承自多个接口,并根据需要实现这些接口的方法。 当类实现多个接口并且这些接口拥有同样的方法名称时,我们需要使用隐式或显示接口实现,以解决命名冲突和实现特定接口的方法的问题。下面将详细讲解 C# 中的隐式和显示实现接口方法。 隐式实现接口方法 为了实现一个接口方法,类所…

    C# 2023年5月15日
    00
  • .Net Core读取Json配置文件的实现示例

    .NET Core读取Json配置文件的实现示例 在.NET Core应用程序中,读取Json格式的配置文件是一项非常常见的任务。在本攻略中,我们将介绍如何在.NET Core应用程序中读取Json格式的配置文件,并提供两个示例说明。 1. 配置文件的格式 在.NET Core应用程序中,配置文件的格式可以是JSON、XML、等。在本攻略中,我们以JSON格…

    C# 2023年5月16日
    00
  • C#线程同步的三类情景分析

    C#线程同步的三类情景分析 在多线程的应用中,为了确保数据的正确性,我们需要对线程进行同步,避免多个线程同时对同一份数据进行修改。C#中提供了多种同步机制,其中包括线程同步的三类情景:Mutex、Monitor和AutoResetEvent。 Mutex Mutex是由操作系统提供的同步原语,可以保证只有一个线程访问临界区。典型的使用方式如下: using …

    C# 2023年6月6日
    00
  • C#实现汽车租赁系统项目

    C# 实现汽车租赁系统项目 汽车租赁系统是一个比较实用的项目,可以用来锻炼 C# 编程技能。下面我们将详细讲解如何实现这个项目。 需求分析 首先我们需要对项目的需求进行分析。汽车租赁系统主要有以下几个功能模块: 用户管理:包括用户登录、注册、修改个人信息等操作。 车型管理:包括添加、删除、修改车型信息等操作。 车辆管理:包括添加、删除、修改车辆信息等操作。 …

    C# 2023年6月7日
    00
  • 学习TraceLogging事件,使用ETW记录,并使用WPA捕获和分析跟踪

    优化响应行为的交互 下载WINDOWS评估和部署工具包 (Windows ADK) 保持默认安装 驱动延迟优化的基本步骤包括: 定义方案并添加 TraceLogging 事件。TraceLogging 是用于日志记录事件的系统,无需清单即可解码,TraceLogging基于windows事件跟踪(ETW),并提供检测代码的简化办法。C#可选的有.NET Ev…

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