文档章节

C#中的动态类型

propagator
 propagator
发布于 2017/08/25 11:51
字数 420
阅读 17
收藏 0

最近研究了一下C#中模拟动态语言的方法,发现可以通过继承DynamicObject来实现。DynamicObject包含的方法可查看msdn或直接查看api,简单说来,DynamicObject提供了一个机制,使得c#可以在运行时处理属性/方法/下标/运算符等操作,并人为定义/修改这些操作的含义。下面给出一个例子来说明。

 

public class DynObj : DynamicObject
{
    Dictionary<string, object> Properties = new Dictionary<string, object>();
    Dictionary<string, object[]> Parameters = new Dictionary<string, object[]>();  // 仅用于记录参数便于回溯
    Dictionary<string, dynamic> Methods = new Dictionary<string, dynamic>();

    // 当找不到函数名称时,进入此方法
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        if (!Parameters.Keys.Contains(binder.Name))
        {
            Parameters.Add(binder.Name, null);
        }

        if (args != null)
        {
            Parameters[binder.Name] = args;
        }

        if (Methods.ContainsKey(binder.Name))
        {
            result = Methods[binder.Name](args);
        }
        else
        {
            result = null;
        }
        return true;
    }

    // 设置动态属性的值,因为方法和属性的设置方法可能一样,所以动态方法也可在此设置
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (!Methods.ContainsKey(binder.Name) && value is Delegate)
        {
            Methods.Add(binder.Name, value);
        }
        else if (!Properties.Keys.Contains(binder.Name))
        {
            Properties.Add(binder.Name, value);
        }

        return true;
    }

    // 获取动态属性的值
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return Properties.TryGetValue(binder.Name, out result);
    }

    // 如果方法已经存在,则不进入TryInvokeMember,直接进入已有方法
    public string Test()
    {
        return "This is a test function";
    }
}

 

上面的类可以通过如下语句调用

dynamic test = new DynObj();
test.a = "hello";
test.b = 10;
test.func1 = new Func<object[], double>((x) => { return Convert.ToInt32(x[0]) + Convert.ToInt32(x[1]); });

Console.WriteLine(test.a);  // 结果为"hello"
Console.WriteLine(test.b);  // 结果为10
Console.WriteLine(test.func1(5, 10));   // 结果为15
Console.WriteLine(test.Test());       // 结果为"This is a test function"
Console.WriteLine(test.Test("Hello"));  // 因为从未定义过,进入TryInvokeMember,但找不到,结果为空

 

类似地,还可以定义下标和运算符的动态处理。

© 著作权归作者所有

共有 人打赏支持
下一篇: Caffe第一个例子
propagator
粉丝 7
博文 28
码字总数 31653
作品 0
昆明
私信 提问
语言设计中的鸭子类型风格

在动态语言的世界里一直流传着一种叫做鸭子类型的风格,其来自谚语:“如果行鸭子一样走路,像鸭子一样呱呱叫,那它就是一只鸭子”。 从鸭子类型,我们可以联想到它的推导,并不在乎类型的真...

justjavac
2013/07/04
269
0
Visual C# .NET 2003 语言的改变

Visual C# .NET 2003 语言的改变 Prashant Sridharan Microsoft Corporation 2002年12月30日 适用于: Microsoft Visual Studio® C# 2003 摘要:为了与欧洲计算机制造商协会 (ECMA) 的 C# 规...

晨曦之光
2012/03/09
42
0
如何快速编写和调试 Emit 生成 IL 的代码

.NET Core/.NET Framework 的 命名空间为我们提供了动态生成 IL 代码的能力。利用这项能力,我们能够在运行时生成一段代码/一个方法/一个类/一个程序集。 大家都知道反射的性能很差,通过缓存...

wpwalter
04/27
0
0
像javascript 一样写c# 。

摘要: .Net 4 中引入了 dynamic 动态类型,着实让我们兴奋的一把,不过相对其它动态语言, 还是有不少差距的。不过借助 CodePlex 上的一个开源项目 Clay,我们可以写出以下不可思议的代码:v...

BryanYang
2013/09/25
0
0
从数据到代码——通过代码生成机制实现强类型编程[上篇]

我不知道大家对CodeDOM的代码生成机制是否熟悉,但是有一点可以确定:如果你使用过Visual Studio,你就应该体验过它带给我们在编程上的便利。随便列举三种典型的代码生成的场景:在创建强类型...

长平狐
2012/09/04
47
0

没有更多内容

加载失败,请刷新页面

加载更多

w, vmstat, top, sar, nload命令查看系统状态信息

w/uptime 查看系统负载 cat /proc/cpuinfo 查看cpu核数 vmstat 监控系统状态,用法 vmstat 1,关键的几列: r, b, swpd, si, so, bi, bo, us, wa top 查看进程使用资源情况 top -c 显示详细的...

野雪球
今天
1
0
小白创建一个spring boot项目

进入 https://start.spring.io/

lilugirl
今天
2
0
Alibaba Java诊断利器Arthas实践--使用redefine排查应用奇怪的日志来源

背景 随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如: [] [] [] No credential found 那么怎样排查这些奇怪的日志从哪里打印出来的呢?因为搞不清...

hengyunabc
今天
2
0
home hosts

home hosts lwk@qwfys:~$ cat /etc/hosts127.0.0.1 localhost127.0.1.1 qwfys192.168.56.101vm600.qwfys.com39.108.212.91alpha1.ppy.com39.108.117.122alpha2.p......

qwfys
今天
3
0
大数据教程(6.1)hadoop生态圈介绍及就业前景

1. HADOOP背景介绍 1.1、什么是HADOOP 1.HADOOP是apache旗下的一套开源软件平台 2.HADOOP提供的功能:利用服务器集群,根据用户的自定义业务逻辑,对海量数据进行分布式处理 3.HADOOP的核心组...

em_aaron
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部