本文是要写的下篇《C#反射及优化用法》的前奏,不能算是下一篇文章的基础的基础吧,有兴趣的朋友请关注一下我的blog,这也有助于提高本人写作的动力。

随着C#的发展,该语言内容不断丰富,开发变得更加方便快捷,C# 的锋利尽显无疑。C# 语言从诞生起就是强类型语言,这一性质到今天不曾改变,我想以后也不会变。既然是强类型语言,那编写任一程序均要求满足下面的基本条件:

1、变量声明必须指明其类型

2、变量类型明确后,其类型在Runtime亦不能改变

代码如下:

    public  class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Like { get; set; }
}
static void Main(string[] args)
{
int a = ;
string s = "abc";
Student student = new Student();
//下面出现编译错误,变量类型在声明后无法再变更
s = a;
student = s;
a = 10.1f;
}

然而,在实际开发中我们经常面临如下几种常见问题:

1、在一个较大的程序程序中,只有一处或很少几处(不超过3处)需要用到 某个或某些类型(如上 Student),其他地方不再需要这些类型。单独声明一个Student类型,所需代码量,可能超过使用该类型时的代码量,投入产出比不划算。

2、在一处程序中,只需要某种类型对象的部分属性或方法参与运算。在这种情况下将该类型对象临时转换为程序所需的部分属性和方法的对象,可使程序更加精简。

3、其他情况........我暂未留意到......欢迎补充........

上面这些 C# 实际开发中常见问题,在 JavaScript 开发中有着比较好的解决方案,如下:

//在此处js中需要模拟一个学生对象
student = {"name":"张三","age":20,"like":"LOL"};
//在此处js中需要模拟一个老师对象
teacher = {"name":"李老师","like":"没收学生手机,自己LOL"};
//此处需要将学生student转换成只有name和age的对象
person = {"name":student.name,"age":student.age};

如果你不熟悉上面的js语法,你可以去百度搜索 “json语法”,告诉你很简单哦(而且很重要)。

匿名对象(匿名类型)

因此C#在3.0版本中吸收了JavaScript脚本语言的这种语法优点,对C#做了相应升级使其也支持这种语法形式(C#依然是强类型语言)。示例代码如下:

static void Main(string[] args)
{
new {Name="张三",Age=,Like="LOL"};
}

上面的C#代码 通过new关键字告诉编译器要创建一个对象,该对象具有Name,Age,Like三个属性,=后为属性对应的值。如此我们避开了“创建一个对象首先要有该对象类型的约束”,因此在开发过程中对于使用较少的类型我们无需再创建单独的类了,上面提到的问题1被解决

现在创建出来的对象没指定具体类型,因此称为匿名对象

Var登场

现在要使用匿名对象,则需要使用变量引用它。虽然我们在创建时没有指定对象的类型,但编译器会在编译过程中帮我们创建一个具有相关属性和方法的类型。此时编译出的类型名称是随机生成的,因此变量类型无法确定。示例如下:

static void Main(string[] args)
{
//XXX为类型声明
//x为引用变量
XXX x = new {Name="张三",Age=,Like="LOL"};
}

虽然我们不知道编译器生成的类型名称,但我们可 让编译器自己根据编译的结果来推断变量类型。此时var关键字便发挥作用了:

static void Main(string[] args)
{
var x = new {Name="张三",Age=,Like="LOL"};
}

var 关键字说明 x 的类型由赋于的值来决定(推定),并能根据编译器推定给出智能提示,如下图:

var使用注意事项:

1、var 仅能声明方法内的局部变量

2、var 声明的变量在被赋值后类型即确定下了,后续程序中不能在赋其他类型的值

3、var x = new object() 没有意义,不要写这样的代码...............

现在有匿名对象和var推断类型的支持,我们就能处理上面提到的问题2。示例代码如下:

        static void Main(string[] args)
{
var x = new { Name = "张三", Age = , Like = "LOL" };
var s = new { Name = x.Name, Age = x.Age };
}

上面仅为示例,如果你熟悉Linq或Entity Framework,那问题2对应的用法将是铺天盖地的.......

动态类型 dynamic 出场

对于匿名类型的使用一般局限于方法的局部,可理解为:随用随定义,用完就消失。有如下情况应该怎么办?

        static void Main(string[] args)
{
var x = GetObject();
} private static XXX GetObject()
{
return new { Name = "张三", Age = , Like = "LOL" };
}

通过GetObject方法返回一个匿名对象,所以方法返回值 类型名称无法确定,此处暂时用XXX代替。在这种情况下返回的类型不确定,可以使用 dynamic 来指明。如下:

        static void Main(string[] args)
{
var x = GetObject();
Console.WriteLine(x.Name);
} private static dynamic GetObject()
{
return new { Name = "张三", Age = , Like = "LOL" };
}

此时方法不会出现语法错误,程序可以成功编译并执行。那么 dynamic 到底做了什么,可以使上面的程序成功编译呢?

dynamic的作用:

1、dynamic 表示动态类型,动态类型的含义就是 程序编写、编译阶段 类型不确定,在Runtime时再通过反射机制确定相关对象的属性或方法。因此编写阶段不会进行语法检测。

2、dynamic 可用来声明 字段、属性、方法参数、方法返回值

3、dynamic 不支持智能提示,因为你写代码时 dynamic  是什么没法知晓(反射)

dynamic 声明的变量,可理解为 object 类型变量。所以给dynamic变量赋任何类型值都正确,但在使用变量来取得某个属性值或调用某方法时(此时程序肯定处于Runtime状态),CLR会检查(反射)所调用的属性或方法是否存在,不存在报运行时异常。

dynamic在 Asp.net Mvc web开发中处处使用,虽然看上去很复杂,本质就上面所说内容。

说明:

var 和 dynamic 看似功能类似,但它们是不同的:

  var dynamic
 声明字段  ×  √
 局部变量  √  √
 方法参数类型  ×  √
 方法返回值类型  ×  √

C# 匿名对象(匿名类型)、var、动态类型 dynamic的更多相关文章

  1. c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic

    比如有一个匿名对象,var  result =......Select( a=>new {  id=a.id, name=a.name});然后Object  obj =  result ;我怎 ...

  2. 六.OC基础--1. id和instancetype类型,2.动态类型检测,3.响应方法,构造方法,4.重写构造方法,5.自定义构造方法

    1. id和instancetype类型, id和instancetype类型区别: 1. id和instancetype都可以用来作为方法的返回值 2. id可以用来定义类型,instancetyp ...

  3. c++ :OOP之静态类型与动态类型

    所谓静态类型即类型指针或引用的字面类型:而动态类型即类型指针或引用的实际类型. 这一对概念一般发生在基类和派生类之间. 如: class Base { ..... } class Derived : ...

  4. C# 匿名对象(匿名类型)、var、动态类型 dynamic——实用之:过滤类属性、字段实用dynamic

    例子 返回一个LIst<oject>类型 而oject含有 30个字段 而我只需要两个字段.这里实用dynamic 和 linq. 上代码: 注意select new {} 为匿名类型,这 ...

  5. 当类型为dynamic的视图模型遭遇匿名对象

    当年在ASP.NET MVC 1.0时代我提到,在开发时最好将视图的Model定制为强类型的,这样可以充分利用静态检查功能进行排错.不过有人指出,这么做虽然易于静态检查,但是定义强类型的Model类型 ...

  6. [javase学习笔记]-6.5 类类型參数与匿名对象

    这一节我们来说说类类型參数和匿名对象. 我们继续用之前的小汽车类吧 class Car { int num;//这是轮胎数属性 String color;//这是颜色属性 String brand;/ ...

  7. var和dynamic的应用 var、动态类型 dynamic 深入浅析C#中的var和dynamic ----demo

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. 利用dynamic解决匿名对象不能赋值的问题

    原文:利用dynamic解决匿名对象不能赋值的问题 关于匿名对象 匿名对象是.Net Framework 3.0提供的新类型,例如: }; 就是一个匿名类,搭配Linq,可以很灵活的在代码中组合数据, ...

  9. C# 匿名对象随笔

      最新更新请访问: http://denghejun.github.io   C#中匿名对象的一般写法是这样的: object o=new {Name="TestName"}; ...

随机推荐

  1. SpringMVC源码情操陶冶-ViewResolver视图解析

    简单分析springmvc是如何解析view视图,并返回页面给前端 SpringMVC配置视图解析器 <bean id="viewResolver" class=" ...

  2. ARM开发(1) 基于STM32的LED跑马灯

    一 跑马灯原理:  1.1 本实验实现2个led的跑马灯效果,即2个led交替闪烁.  1.2 实验思路:根据电路图原理,给led相关引脚赋予高低电平,实现电路的导通,使led灯发光.  1.3 开发 ...

  3. Ubuntu上安装PHP环境-mysql+apache+php-Linux操作系统

    安装MYSQL   1. sudo apt-get install mysql-server 或者 apt-get isntall mysql-client   2. 安装过程中会提示设置密码,注意设 ...

  4. RMAN备份到共享存储失败(win平台)

    RMAN备份到共享存储失败(win平台) 之前在<Win环境下Oracle小数据量数据库的物理备份>这篇文章中,介绍了在win平台下对于小数据量的数据库的物理备份设计. 文中重点提到,强烈 ...

  5. MSDTC启用——分布式事务

    一.前言 最近在做一个项目的时候使用了.NET中的System.Transactions(分布式事务),当项目开发完成以后,调用的时候遇到了MSDTC的问题,在查阅了相关资料后将这个问题解决了,大致的 ...

  6. (转)sizeof

    数据类型的大小(即所占字节数)以及能够表示的数据范围是与编译器和硬件平台有关的."float.h"头文件(如vc6.0,在include目录下)通常定义了基本数据类型能够表示的数据 ...

  7. 【JAVASCRIPT】React学习- 杂七杂八

    摘要 记录 React 学习中的小细节 setState setState 有一定的时间延迟,如果需要保证 setState 之后执行某些动作,可以采用以下方法 this.setState({ vis ...

  8. Java curator操作zookeeper获取kafka

    Java curator操作zookeeper获取kafka Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更 ...

  9. ORACLE - 系统参数调整

    一.内存调整 oracle 11g中,ORACLE把SGA与PGA统一管理,总和为memory_target参数的设定,也就是MAX(SGA+PGA)<= memory_target(当然可以在 ...

  10. 香港服务器PING知识知多少?

    香港服务器PING命令简介: PING命令是用来检查要到达的目标IP地址并记录结果,显示目标是否响应以及接收答复所需的时间.如果在传递到目标过程中有错误,ping 命令将显示错误消息. 我们在HOST ...