有朋友跟老周说,动态类型是干吗的,他不太熟悉,希望老周可以讲一讲。没事,这事情老周也比较TMD乐意做的,因为老周写的这些烂文本来就是为了普及基础知识的,坚定不移地为社会基础教育而服务。

首先,咱们要知道啥是动态类型,既然叫“动态”了,当然和“静态”相对而言的,但你得注意,这里的动态静态不是指类型的动与静,不要以为动态类型就是实例类型,也不要认为静态类型就是static关键定义的类型。

非也,这里所讨论的dynamic是指在编译阶段不做解析和检查,而在运行阶段才调用的类型。你不要在意书本上讲得多么抽象难懂,你记得这句话就行了,编译是啥,你懂吧,那就好了。

动态技术可以用起来很简单,也可以很复杂,重点是看你怎么用罢了。如果你需要完全自定义动态的行为,当然得很复杂,因为你要自己来实现动态操作的逻辑。

本次老周就先讲一些简单的,故称为“娱乐篇”,改天,再说说“高级篇”,看看怎么自定义动态行为。

在C#语言中,用dynamic关键字来声明动态类型,实例化时你可以赋任意值。比如这样:

            dynamic d = 3000u;
Console.WriteLine(d.GetType()); dynamic m = "子曰:有朋自远方来,记得请吃饭";
Console.WriteLine(m.GetType());

变量d和m都被声明为动态的,你猜这几行代码运行后会输出什么。dynamic关键字声明的变量可以赋任何类型的值。比如这个例子,d赋的uint类型的值3000,后面的u就表示这个数值是uint类型;m赋的是字符串值。因此,在运行阶段,会根据变量中具体的值来判断其类型,d变量存放的值的类型为System.UInt32,m存放的值类型为System.String。

所以,输出的内容为:

System.UInt32
System.String

你还可以向动态类型的属性赋值,属性名都是动态生成的,所以在输入时是没有智能提示的,因为是运行时才解析,所以,赋值和取值时的属性名字一定要一致,不然就取不到值了。

举个例子:

            dynamic dd = new ExpandoObject();
// 赋值
dd.Name = "小王";
dd.Age = ; // 取值
Console.WriteLine($"此人名叫 {dd.Name} ,年龄 {dd.Age}。");

ExpandoObject是专为动态行为而设计的类型,因为此时要向动态类型的实例的属性赋值,因此属于复合类型,在用dynamic关键字声明变量后,就必须用一个类来实例化,ExpandoObject类就是这个用途。

然后,赋了Name和Age属性的值,属性名字可以随便写,因为是动态的,编译时不会检查;然后在读取属性的值时,属性名一定要和刚才赋值时的名字一致,不然你是取不到值的。

所以得到结果如下:

此人名叫 小王 ,年龄 35。

实际上,ExpandoObject类显式实现了 IDictionary<string,object> 接口,所以,我们可以知道,其实它里面就是用一个字典来存储动态赋值的数值的,键的类型为字符串,表示属性名;值的类型为object,表示任何类型。

不信?咱们把它里面的字典数据输出来:

            IDictionary<string, object> dic = (IDictionary<string, object>)dd;
foreach (var pv in dic)
{
Console.WriteLine($"Key = {pv.Key} , Value = {pv.Value}");
}

然后得到结果如下:

Key = Name , Value = 小王
Key = Age , Value = 35

所为为什么不管你如何动态设置属性,它都可以进行解析,就是这个原因,里面用一个字典来负责存取数据。

由于这个类也实现了INotifyPropertyChanged接口,所以,还可以用它来做数据绑定。

看例子:在WPF中用动态对象来进行双向绑定。

XAML如下:

    <Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Name="panel1">
<TextBlock Text="{Binding Path=Text1,Mode=OneWay}"/>
<TextBlock Text="{Binding Path=Text2,Mode=OneWay}"/>
</StackPanel>
<StackPanel Grid.Row="1" Name="panel2">
<TextBox Text="{Binding Path=Text1,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Text="{Binding Path=Text2,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Grid>

然后在代码中初始化动态对象,并让这两个StackPanel的DataContext都引用同一个动态对象实例。

        dynamic obj = null;
public MainWindow()
{
InitializeComponent();
// 初始化
obj = new ExpandoObject(); obj.Text1 = "item 1";
obj.Text2 = "item 2"; this.panel1.DataContext = this.panel2.DataContext = obj;
}

运行之后,在下面的两个TextBox中输入内容,然后你会看到上面的TextBlock中的文本也会跟着一起变化。

好,今天老周给大家说了动态对象的一些娱乐级别的功能,用起来挺简单方便。过几天有空,再给大伙儿们说说高端篇,介绍如何自己来实现支持动态行为的类型。

示例代码下载

【.net深呼吸】动态类型(娱乐篇)的更多相关文章

  1. 【.net深呼吸】动态类型(高级篇)

    前面老周给大家介绍了动态类型使用的娱乐级别用法,其实,在很多情景下,娱乐级别的用法已经满足需求了. 如果,你想自己来控制动态类型的行为和数据的存取,那么,就可以考虑用今天所说的高大上技术了.比如,你希 ...

  2. 【.NET深呼吸】动态类型(扩充篇)

    前面两文中,老周已向大家介绍了关于动态类型对象的两种级别的使用方案,本篇呢,老周再讲一个自定义动态类型的例子. 前面给大家演示的例子中,动态类型中包装的是字典类型来存储数据的,这一次咱们换一种风味,老 ...

  3. Python 学习 第四篇:动态类型模型

    Python的变量不用声明,赋值之后就可以直接使用,类型是在运行过程中自动确定的,这就是动态类型模型.该模型把变量和对象设计成两个不同的实体,对象是存储数据的地方,对象的类型是由初始值自动决定的,而变 ...

  4. Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示

    Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...

  5. 【转】解析JDK 7的动态类型语言支持

    http://www.infoq.com/cn/articles/jdk-dynamically-typed-language Java虚拟机的字节码指令集的数量自从Sun公司的第一款Java虚拟机问 ...

  6. Net 4.0 之 Dynamic 动态类型

    Net 4.0 之 Dynamic 动态类型 本文主要旨在与网友分享.Net4.0的Dynamic 对Duck Type 的支持.     一..net4.0主要新特性 .Net4.0在.Net3.5 ...

  7. 享受Python和PHP动态类型检查语言的快感

    前言 写这文章的时候特地查了资料,以确保我没有说错关于Python和PHP的类型机制. 所以这里放一张图,关于强弱类型与动态/静态类型检查的区分 从分类上看,PHP属于弱类型语言,而Python属于强 ...

  8. C#基本语法 - .Net 4.0 之 Dynamic 动态类型

      一..net4.0主要新特性 .Net4.0在.Net3.5基础上新增的主要特性有:可选参数.命名参数和Dynamic.具体请阅生鱼片的这篇博文.这里我们着重讲解C#4.0的Dynamic特性,对 ...

  9. C#如何根据DataTable生成泛型List或者动态类型list

    背景:在项目中,sql语句检索返回DataTable,然后根据检索结果做进一步的操作,本篇文章即是介绍如何将DataTable快速生成泛型List返回. 假设存在如下学生类: public class ...

随机推荐

  1. Hangfire项目实践分享

    Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(De ...

  2. 01.SQLServer性能优化之----强大的文件组----分盘存储

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...

  3. 我是如何在SQLServer中处理每天四亿三千万记录的

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  4. Unity游戏内版本更新

    最近研究了一下游戏内apk包更新的方法. ios对于应用的管理比较严格,除非热更新脚本,不太可能做到端内大版本包的更新.然而安卓端则没有此限制.因此可以做到不跳到网页或应用商店,就覆盖更新apk包. ...

  5. 按需加载.js .css文件

    首先,理解按需加载当你需要用到某个js里面的函数什么鬼,或者某个css里的样式的时候你才开始加载这个文件. 然后是怎样实现的,简单来说就是在js中动态的createElem<script> ...

  6. OpenCV模板匹配算法详解

    1 理论介绍 模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否“相似”,当相似度足够高时,就认为找到了我们的目标.OpenCV ...

  7. Aaron Stannard谈Akka.NET 1.1

    Akka.NET 1.1近日发布,带来新特性和性能提升.InfoQ采访了Akka.net维护者Aaron Stannard,了解更多有关Akka.Streams和Akka.Cluster的信息.Aar ...

  8. 使用python自动生成docker nginx反向代理配置

    由于在测试环境上用docker部署了多个应用,而且他们的端口有的相同,有的又不相同,数量也比较多,在使用jenkins发版本的时候,不好配置,于是想要写一个脚本,能在docker 容器创建.停止的时候 ...

  9. arcgis api for js入门开发系列四地图查询(含源代码)

    备注:由于实现本篇功能的需求,修改了地图数据的dlsearch.mxd,然后更新了地图服务,需要的在文章最后有提供最新的mxd以及源代码下载的 上一篇实现了demo的地图工具栏,本篇新增地图查询功能, ...

  10. 【干货分享】流程DEMO-事务呈批表

    流程名: 事务呈批表  业务描述: 办公采购.会议费用等事务的申请.流程发起时,会检查预算,如果预算不够,将不允许发起费用申请,如果预算够用,将发起流程,同时占用相应金额的预算,但撤销流程会释放相应金 ...