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

下面是详细的攻略:

C#Dynamic之:ExpandoObject,DynamicObject,DynamicMetaObject的应用(下)

一、ExpandoObject

ExpandoObject是一个动态类型,它允许我们在运行时添加或删除属性,甚至可以动态更改属性的类型。ExpandoObject非常方便,可以用来处理一些未知的数据结构。

1. 添加属性

我们可以使用ExpandoObject来动态地添加属性。例如,我们可以利用它来创建一个JavaScript风格的字典。

dynamic dynamicObj = new ExpandoObject();
dynamicObj.first = "John";
dynamicObj.last = "Doe";
dynamicObj.address = new ExpandoObject();
dynamicObj.address.street = "123 Main St";
dynamicObj.address.city = "Seattle";
dynamicObj.address.zip = "98101";

在上面的示例中,我们创建了一个dynamic类型的对象dynamicObj,然后动态地添加了first、last、address三个属性。其中,address属性又是一个ExpandoObject类型的对象,我们又动态地为它添加了street、city和zip三个属性。

2. 获取属性

我们可以像访问普通对象一样,通过.操作符来访问ExpandoObject上的属性。

Console.WriteLine(dynamicObj.first); // John
Console.WriteLine(dynamicObj.last); // Doe
Console.WriteLine(dynamicObj.address.street); // 123 Main St
Console.WriteLine(dynamicObj.address.city); // Seattle
Console.WriteLine(dynamicObj.address.zip); // 98101

3. 删除属性

我们也可以使用ExpandoObject来动态地删除属性。

((IDictionary<string, object>)dynamicObj).Remove("address");

在上面的示例中,我们将address属性从dynamicObj中删除了。

二、DynamicObject

DynamicObject是一个抽象类,它提供了一些方法来让我们自定义动态对象的行为。我们可以继承DynamicObject类来创建自己的动态类型,并重写它提供的方法来实现所需的行为。

1. 重写TryGetMember方法

我们可以通过重写DynamicObject类的TryGetMember方法来提供对动态对象的成员的访问行为。

public class DynamicDictionary : DynamicObject
{
    private 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 void Add(string key, object value)
    {
        _dictionary[key.ToLower()] = value;
    }

    // other methods omitted for brevity
}

在上面的示例中,我们创建了一个DynamicDictionary类,继承自DynamicObject,它包含了一个Dictionary,就是我们要动态添加属性的字典。我们重写了TryGetMember方法,当访问DynamicDictionary的一个成员时,它会尝试从字典中获取该成员。我们还添加了一个Add方法,用来动态地向字典中添加属性。

使用示例:

dynamic dict = new DynamicDictionary();
dict.Name = "John";
dict.Age = 20;

Console.WriteLine(dict.Name); // John
Console.WriteLine(dict.Age); // 20

在上面的示例中,我们创建了一个dynamic类型的对象dict,它是DynamicDictionary的实例。然后我们动态地为dict添加了两个属性Name和Age。接着,我们通过dict.Name和dict.Age来访问这两个属性,它们的值分别是"John"和20。

2. 重写TryInvokeMember方法

我们还可以通过重写DynamicObject类的TryInvokeMember方法来提供对动态对象的方法调用行为。

public class DynamicCalculator : DynamicObject
{
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        var arg1 = (double)args[0];
        var arg2 = (double)args[1];
        switch (binder.Name.ToLower())
        {
            case "add":
                result = arg1 + arg2;
                return true;
            case "subtract":
                result = arg1 - arg2;
                return true;
            case "multiply":
                result = arg1 * arg2;
                return true;
            case "divide":
                result = arg1 / arg2;
                return true;
            default:
                result = null;
                return false;
        }
    }
}

在上面的示例中,我们创建了一个DynamicCalculator类,它继承自DynamicObject。我们重写了TryInvokeMember方法,当我们调用DynamicCalculator的一个方法时,它会根据方法名动态执行相应的操作。例如,当我们调用Add(2,3)时,它会返回5,因为2+3=5。

使用示例:

dynamic calc = new DynamicCalculator();
Console.WriteLine(calc.Add(2, 3)); // 5
Console.WriteLine(calc.Subtract(5, 2)); // 3
Console.WriteLine(calc.Multiply(3, 4)); // 12
Console.WriteLine(calc.Divide(10, 2)); // 5

在上面的示例中,我们创建了一个dynamic类型的对象calc,它是DynamicCalculator的实例。然后我们动态地调用了它的四个方法Add、Subtract、Multiply和Divide,它们的返回值分别是5、3、12和5。

三、DynamicMetaObject

DynamicMetaObject是DynamicObject的一个扩展类,它提供了一些方法来让我们更加灵活地定义动态对象的行为。我们可以继承DynamicMetaObject类来创建自己的动态类型,并重写它提供的方法来实现所需的行为。

1. 重写GetDynamicMemberNames方法

我们可以通过重写DynamicMetaObject类的GetDynamicMemberNames方法来动态地返回动态对象的所有属性。

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

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return _dictionary.Keys;
    }

    // other methods omitted for brevity
}

在上面的示例中,我们重写了GetDynamicMemberNames方法,它会返回_dynamicDictionary的所有属性名。这使得我们可以使用foreach循环来遍历_dynamicDictionary的所有属性。

使用示例:

dynamic dict = new DynamicDictionary();
dict.Name = "John";
dict.Age = 20;

foreach (var prop in dict)
{
    Console.WriteLine("{0} = {1}", prop, dict[prop]);
}

在上面的示例中,我们创建了一个dynamic类型的对象dict,它是DynamicDictionary的实例。然后我们动态地为dict添加了两个属性Name和Age。接着,我们使用foreach循环遍历dict的所有属性,并输出它们的名称和值。

2. 重写TryConvert方法

我们还可以通过重写DynamicMetaObject类的TryConvert方法来提供类型转换的行为。例如,当我们将一个动态对象转换为某个具体的类型时,它会调用我们重写的TryConvert方法,来决定如何将动态对象转换为目标类型。

public class DynamicPerson : DynamicObject
{
    private string _name;
    private int _age;

    public DynamicPerson(string name, int age)
    {
        _name = name;
        _age = age;
    }

    public override bool TryConvert(ConvertBinder binder, out object result)
    {
        if (binder.Type == typeof(string))
        {
            result = string.Format("{0} ({1})", _name, _age);
            return true;
        }
        else if (binder.Type == typeof(int))
        {
            result = _age;
            return true;
        }
        else
        {
            result = null;
            return false;
        }
    }
}

在上面的示例中,我们创建了一个DynamicPerson类,它继承自DynamicObject。我们重写了TryConvert方法,当我们将DynamicPerson对象转换为字符串或整数时,它会返回相应的结果。

使用示例:

dynamic person = new DynamicPerson("John Doe", 20);
string strNameAge = (string)person;
int intAge = (int)person;

Console.WriteLine(strNameAge); // John Doe (20)
Console.WriteLine(intAge); // 20

在上面的示例中,我们创建了一个dynamic类型的对象person,它是DynamicPerson的实例。然后,我们将person分别转换为字符串和整数,它们分别是"John Doe (20)"和20。

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

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

相关文章

  • 在 ASP.NET Core 中为 gRPC 服务添加全局异常处理

    在ASP.NET Core中,gRPC是一种常见的跨平台通信方式,它可以帮助开发者在不同的平台之间进行高效的通信。在本攻略中,我们将详细介绍如何为gRPC服务添加全局异常处理,并提供两个示例来说明其用法。 以下是两个示例,介绍如何为gRPC服务添加全局异常处理: 示例一:使用全局异常过滤器 首先,我们需要创建一个全局异常过滤器: public class G…

    C# 2023年5月15日
    00
  • C#使用private font改变PDF文件的字体详解

    下面是 “C#使用private font改变PDF文件的字体详解” 的完整攻略。 什么是Private Font Private Font是一种自定义字体,可以正常安装和使用,但在未安装该字体的计算机上会出现显示问题。因此我们需要在程序中安装该字体,在PDF文件中使用该字体。 安装Private Font 首先在项目目录下新建一个名为“Fonts”的文件夹…

    C# 2023年6月3日
    00
  • C#函数式编程中的部分应用详解

    C#函数式编程中的部分应用详解 简介 在函数式编程中,部分应用(Partial application)是一种非常重要的技术手段。它指的是对于一个有多个参数的函数,在给定一部分参数后,返回一个新函数,该函数只需要接受剩余的参数即可完成执行。这个过程中,新函数的参数比原函数的参数少。 实现 在C#中,我们可以通过使用实例化委托的方式来实现部分应用。 deleg…

    C# 2023年6月6日
    00
  • C# WINFORM自定义异常处理方法

    下面就为您详细讲解“C# WINFORM自定义异常处理方法”的完整攻略。 什么是异常处理? 首先,我们需要理解什么是异常处理。在编写程序时,有些运行时错误是可以预见的,比如除数为零、数组下标越界、文件不存在等。当这些错误出现时,我们需要给用户一个合理的提示,让用户理解并修复这些问题。这就是异常处理。 在C#中,异常处理通常使用try-catch代码块来完成。…

    C# 2023年6月6日
    00
  • c# 爬取优酷电影信息(1)

    下面是针对“c# 爬取优酷电影信息(1)”攻略的详细讲解。 1. 项目概述 该项目旨在使用C#编写一个网页爬虫,从优酷电影网站上爬取指定类型电影的信息,包括电影名称、导演、演员、上映时间、评分等。具体实现时,我们将使用HtmlAgilityPack解析HTML页面并提取数据。 2. 实现步骤 2.1 确定目标URL与请求方式 我们首先需要确定需要爬取的目标页…

    C# 2023年6月2日
    00
  • C# BinaryReader.ReadBytes – 读取字节数组

    BinaryReader.ReadBytes 方法是 .NET Framework 内置的一个方法,可以用来从流中读取指定长度的字节,并将其存储在字节数组中。该方法返回一个字节数组,表示从流中读取的数据。 使用该方法需要先创建一个 BinaryReader 实例,该实例包含了一个可以读取的流。然后可以调用 ReadBytes 方法来读取指定长度的字节。该方法…

    C# 2023年4月19日
    00
  • ASP.NET(C#)中遍历所有控件

    遍历所有控件可以使用递归方法,递归遍历每个控件,并递归遍历控件中的所有子控件。 以下是C#中遍历所有控件的完整攻略: 步骤1:创建递归方法 创建递归方法,并在其中遍历每个控件: private void TraverseControls(Control control) { foreach (Control childControl in control.C…

    C# 2023年6月3日
    00
  • .Net Core日志记录之第三方框架Serilog

    .NET Core日志记录之第三方框架Serilog 在本攻略中,我们将深入讲解如何使用第三方框架Serilog进行.NET Core日志记录,并提供两个示例说明。 什么是Serilog? Serilog是一个.NET Core日志记录框架,它提供了一种简单、灵活、可扩展的方式来记录应用程序的日志。Serilog支持多种输出格式和目标,包括控制台、文件、数据…

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