比如有一个匿名对象,var result =......Select( a=>new { id=a.id, name=a.name});
然后Object obj = result ;
我怎么从obj 中取出 id和name ?
dynamic a = obj;
var bb = a.id;
var cc = a.name;
如果要重复使用数据模式,那么最可行的做法是重构代码,立刻增加一个模式定义,例如
1
2
3
4
5
|
public class AA
{ public string id;
public string name;
} |
编程设计时代码会呈现有很多“层次”,比如说有人甚至说非要
1
2
|
var x = obj; var y = eval( "obj.id" );
|
这种,他非要字符串才“爽”。
编程要尽可能地强类型、按照接口设计代码,一个程序中的反射代码不过也就是万分之一而已,千方百计避免滥用。那么从设计理念上就要保持一种“规范”。
动态语言语法有它的好处,由她的方便性,这个是不可否认的。至于说什么时候该使用动态的特性,让运行时——而非编译时——才出现bug、系统崩溃提示(不怕在用户面前丢脸),那就要靠经验来判断。所以不要轻易滥用动态特性。
c# dynamic动态类型和匿名类
dynamic类型
简单示例
dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
expando.Id = 1;
expando.Name = "Test";
string json = Utils.ConvertJson.JsonEncode(expando); //输出{Id:1,Name:'Test'}
//动态添加字段
List<string> fieldList = new List<string>() { "Name","Age","Sex"}; //From config or db
dynamic dobj = new System.Dynamic.ExpandoObject();
var dic = (IDictionary<string, object>)dobj;
foreach (var fieldItem in fieldList)
{
dic[fieldItem] = "set "+fieldItem+" value"; /*实现类似js里的 动态添加属性的功能
var obj={};
var field="Id";
eval("obj."+field+"=1");
alert(obj.Id); //1 */
}
var val = dobj.Name; //“set Name value”
var val1=dobj.Age;//”set Age value“
枚举该对象所有成员
foreach (var fieldItem in (IDictionary<String, Object>)dobj)
{
var v = (fieldItem.Key + ": " + fieldItem.Value);
}
匿名类
//var aaaa = new {Id=1,Name="Test"}; //匿名类字段只读不可写
dynamic aaaa = new {Id=1,Name="Test"}; //匿名类字段只读不可写
aaaa.Id = 2; //不可写 报错无法为属性或索引器“<>f__AnonymousType1<int>.Id”赋值 - 它是只读的
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject("{Name:'aa',Sex:'Male',Age:11}");
var name = obj.Name.Value; //aa
原文地址:http://www.cnblogs.com/xuejianxiyang/p/4964739.html
随着C#的发展,该语言内容不断丰富,开发变得更加方便快捷,C# 的锋利尽显无疑。C# 语言从诞生起就是强类型语言,这一性质到今天不曾改变,我想以后也不会变。既然是强类型语言,那编写任一程序均要求满足下面的基本条件:
1、变量声明必须指明其类型
2、变量类型明确后,其类型在Runtime亦不能改变
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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 = 10;
string s = "abc" ;
Student student = new Student();
//下面出现编译错误,变量类型在声明后无法再变更
s = a;
student = s;
a = 10.1f;
} |
然而,在实际开发中我们经常面临如下几种常见问题:
1、在一个较大的程序程序中,只有一处或很少几处(不超过3处)需要用到 某个或某些类型(如上 Student),其他地方不再需要这些类型。单独声明一个Student类型,所需代码量,可能超过使用该类型时的代码量,投入产出比不划算。
2、在一处程序中,只需要某种类型对象的部分属性或方法参与运算。在这种情况下将该类型对象临时转换为程序所需的部分属性和方法的对象,可使程序更加精简。
3、其他情况........我暂未留意到......欢迎补充........
上面这些 C# 实际开发中常见问题,在 JavaScript 开发中有着比较好的解决方案,如下:
1
2
3
4
5
6
|
//在此处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#依然是强类型语言)。示例代码如下:
1
2
3
4
|
static void Main( string [] args)
{ new {Name= "张三" ,Age=20,Like= "LOL" };
} |
上面的C#代码 通过new关键字告诉编译器要创建一个对象,该对象具有Name,Age,Like三个属性,=后为属性对应的值。如此我们避开了“创建一个对象首先要有该对象类型的约束”,因此在开发过程中对于使用较少的类型我们无需再创建单独的类了,上面提到的问题1被解决。
现在创建出来的对象没指定具体类型,因此称为匿名对象。
Var登场
现在要使用匿名对象,则需要使用变量引用它。虽然我们在创建时没有指定对象的类型,但编译器会在编译过程中帮我们创建一个具有相关属性和方法的类型。此时编译出的类型名称是随机生成的,因此变量类型无法确定。示例如下:
1
2
3
4
5
6
|
static void Main( string [] args)
{ //XXX为类型声明
//x为引用变量
XXX x = new {Name= "张三" ,Age=20,Like= "LOL" };
} |
虽然我们不知道编译器生成的类型名称,但我们可 让编译器自己根据编译的结果来推断变量类型。此时var关键字便发挥作用了:
1
2
3
4
|
static void Main( string [] args)
{ var x = new {Name= "张三" ,Age=20,Like= "LOL" };
} |
var 关键字说明 x 的类型由赋于的值来决定(推定),并能根据编译器推定给出智能提示,如下图:
var使用注意事项:
1、var 仅能声明方法内的局部变量
2、var 声明的变量在被赋值后类型即确定下了,后续程序中不能在赋其他类型的值
3、var x = new object() 没有意义,不要写这样的代码...............
现在有匿名对象和var推断类型的支持,我们就能处理上面提到的问题2。示例代码如下:
1
2
3
4
5
|
static void Main( string [] args)
{
var x = new { Name = "张三" , Age = 20, Like = "LOL" };
var s = new { Name = x.Name, Age = x.Age };
}
|
上面仅为示例,如果你熟悉Linq或Entity Framework,那问题2对应的用法将是铺天盖地的.......
动态类型 dynamic 出场
对于匿名类型的使用一般局限于方法的局部,可理解为:随用随定义,用完就消失。有如下情况应该怎么办?
1
2
3
4
5
6
7
8
9
|
static void Main( string [] args)
{
var x = GetObject();
}
private static XXX GetObject()
{
return new { Name = "张三" , Age = 20, Like = "LOL" };
}
|
通过GetObject方法返回一个匿名对象,所以方法返回值 类型名称无法确定,此处暂时用XXX代替。在这种情况下返回的类型不确定,可以使用 dynamic 来指明。如下:
1
2
3
4
5
6
7
8
9
|
static void Main( string [] args)
{
var x = GetObject();
Console.WriteLine(x.Name);
}
private static dynamic GetObject()
{
return new { Name = "张三" , Age = 20, 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,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
您可能感兴趣的文章:
原文链接:http://www.cnblogs.com/dw039/p/7472119.html
这篇文章给大家介绍了C#中的var和dynamic的相关知识,var和dynamic的本质区别是类型判断的时间不同,前者是编译时,后者是运行时。具体内容详情大家通过本文学习下吧
在理解var
和dynamic
关键字之前,让我们先了解一下编程语言的类别。
C#中有两类编程语言:
- 静态类型语言类别
- 动态语言类别
静态类型语言
静态类型语言也被称为强类型语言。所谓强类型语言,通俗的讲,就是在编译过程中执行类型检查的语言。我们举个简单的例子,比如我们知道一个方法的返回类型,但是如果返回类型过于复杂,那么我推荐你使用var
。但是,当你明确知道返回类型时,或者返回的只是简单类型,那么我推荐你直接使用该数据类型来声明方法返回类型,就像平时我们经常用string
、int
、bool
等修饰符声明返回类型一样。
接下来让我们来了解C#中的var
关键字。
var
关键字是定义数据类型的间接方式
当你定义特定类型的var
时:
string str = "Test";
这种写法被称为显式类型的声明,也被称为直接声明。
当你使用var
关键字定义一个变量时:
var str = "Test";
这被称为隐式类型声明或间接类型声明。
一般情况下,编译器会在编译过程中验证数据,并在编译过程中创建适当的类型。在此实例中,编译器将检查Test
,并在生成IL代码时将var
关键字替换为字符串。
var
关键字在编译时静态的定义数据类型,而不是在运行时,即:一旦定义了数据类型,它将不会在运行时更改。
让我们看下面的例子:
var str = "Test";str = 123;
生成这个应用程序,如下图所示,将在str = 123
处的隐式转换抛出编译错误
如果将鼠标移动到第一行的str
上,实际上是可以获得局部变量字符串str
的值,如下图所示
我们可以通过使用ILDasm.exe打开这个exe/dll来验证这个结果。
何时使用var
对于像int
、double
、string
等简单数据类型,我们最好使用特定的数据类型来声明变量,以免让事情变得复杂。但当你创建了一个很大的类,那么为了方便创建对象,你最好使用var关键字。还有一种约定俗成的习惯,当我们使用LINQ
或Anonymous
类型时,必须使用var
关键字。
动态类型语言
动态类型语言是指在运行时执行类型检查的语言。如果您不知道您将获得或需要分配的值的类型,则在此情况下,类型是在运行时定义的。让我们看看下面的例子。
1
2
3
4
5
6
|
class Program { static void Main(string[] args)
{
dynamic str = "Test" ;
}
} |
现在,如果您输入str.
,那么您将无法获得任何智能提示,如下图所示。
此例中,在为str
分配值之后,如果执行一些数学运算,它不会给出任何错误信息。
1
2
3
4
5
6
7
|
class Program { static void Main(string[] args)
{
dynamic str = "Test" ;
str++;
}
} |
很明显,现在就算我生成应用程序,也不会有错误产生,应用程序也会成功生成:
但是,如果你运行这个应用程序,对不起,VS会给你如下所示的运行时错误:
dynamic
关键字内部使用反射,感兴趣的童鞋可以自行研究一下。
小结
var
和dynamic
关键字之间的主要区别在于绑定时间不一样:var
是早期绑定,dynamic
绑定则会在运行时进行。
var
实际上是编译器抛给我们的语法糖,一旦被编译,编译器就会自动匹配var
变量的实际类型,并用实际类型来替换该变量的声明,等同于我们在编码时使用了实际类型声明。而dynamic
被编译后是一个Object
类型,编译器编译时不会对dynamic
进行类型检查。
.Net 4.0之前的运行时的动态调用一般是通过反射来实现,但是反射的代码的可读性不高。.Net 4.0之后使用dynamic
就好得多,因为dynamic
是一种静态类型,完全可以像其它类型一样的声明和调用,而不用写反射相关的代码。
合理的运用dynamic
可以让你的代码更加的简洁,而且比直接使用反射性能更好(反射没有优化处理的前提),因为dynamic
是基于DLR
,第一次运行后会缓存起来。其实有心的同学会发现.net的类库里面很多地方都用了dynamic
这个东西,例如:mvc
中的ViewBag
就是一个很好的例子。一般情况下,如果开发者不知道方法和方法的返回类型是否公开,请使用dynamic
关键字。
补充:C# var和dynamic的用法和理解
var和dynamic的本质区别是类型判断的时间不同,前者是编译时,后者是运行时。
1.var在声明变量方面简化语法(只能是局部变量),在编译时交给编译器推断。
2.dynamic也是为简化语法而生的,它的类型推断是交给系统来执行的(运行时推断类型)。
3.var不能用于字段、参数等,而dynamic则可以。
4.var在初始化的时候就确定了类型。
5.dynamic可以用于方法字段、参数、返回值以及泛型参数,把动态发挥的淋漓尽致。
6.dynamic在反射方面做的可以,只是我自己没有尝试过。
7.var是C# 3.0的产物,dynamic是C# 4.0的产物。
最后还得关心一下效率问题:
越底层的效率越高
可以说是 传统强类型 >= var > dynamic,所以用dynamic的时候还得考虑性能和效率!
总结
以上所述是小编给大家介绍的C#中的var和dynamic ,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!
您可能感兴趣的文章:
原文链接:http://www.cnblogs.com/yayazi/p/8998610.html