.Net 的动态对象(一)概念
前言
在js里面我们想要给一个对象的属性赋值,或者调用一个对象里面的方法,一般是:
var o = {};
o.name = 'yyy';
o.ShowName=function(name){//TODO}
如果是在 .net中,不使用动态对象的话,就只有先定义好我们的属性和方法,再直接去调用,有了动态对象后,我们也可以做类似的事情
dynamic model = new ExpandoObject();
model.name = "xx";
model.ShowName = new Func<string, string>((name) =>
{
return "the name property is " + name;
});
model.ShowOwenName = new Func<dynamic, string>((sender) =>
{
return "the name property is " + sender.name;
});
Console.WriteLine(model.name);
Console.WriteLine(model.ShowName("x"));
Console.WriteLine(model.ShowOwenName(model));
概述
- dynamic是FrameWork4.0的新特性。dynamic的出现让C#具有了弱语言类型的特性。编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性
- var和dynamic完全是两个概念,var实际上是编译期抛给我们的“语法糖”,一旦被编译,编译期会自动匹配var 变量的实际类型,并用实际类型来替换该变量的申明,这看上去就好像我们在编码的时候是用实际类型进行申明的。而dynamic被编译后,实际是一个object类型,只不过编译器会对dynamic类型进行特殊处理,让它在编译期间不进行任何的类型检查,而是将类型检查放到了运行期。
- 任何实例都能隐式转换为dynamic类型实例,所以在类型装换的时候用就很方便
- 简化反射的写法,常见的反射写法:
public class DynamicSample { public string Name { get; set; } public int Add(int a, int b) { return a + b; } } var ass = Assembly.LoadFile("xx"); var instance = ass.CreateInstance("DynamicSample"); var addMethod = typeof(instance).GetMethod("Add"); int re = (int)addMethod.Invoke(dynamicSample, new object[] { 1, 2 });
在有了动态对象后
var ass = Assembly.LoadFile("xx"); dynamic instance = ass.CreateInstance("DynamicSample"); instance.Add(1,2)
自定义DynamicObject
自定义DynamicObject 包含了大量的虚方法,所以这些我们都是可以重写的
public class DynamicObject : IDynamicMetaObjectProvider
{
protected DynamicObject(); //所以我们不能直接的实例化一个DynamicObject对象,而是需要我们自定义一个DynamicObject
public virtual IEnumerable<string> GetDynamicMemberNames();
public virtual DynamicMetaObject GetMetaObject(Expression parameter);
public virtual bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result);
public virtual bool TryConvert(ConvertBinder binder, out object result);
public virtual bool TryCreateInstance(CreateInstanceBinder binder, object[] args, out object result);
public virtual bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes);
public virtual bool TryDeleteMember(DeleteMemberBinder binder);
public virtual bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result);
public virtual bool TryGetMember(GetMemberBinder binder, out object result);
public virtual bool TryInvoke(InvokeBinder binder, object[] args, out object result);
public virtual bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result);
public virtual bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value);
public virtual bool TrySetMember(SetMemberBinder binder, object value);
public virtual bool TryUnaryOperation(UnaryOperationBinder binder, out object result);
}
在最开始例子里面通过ExpandoObject展示了如何动态的添加属性和方法,
DynamicObject跟ExpandoObject最大的区别就是,我们可以通过继承DynamicObject,自己来决定动态对象如何执行,就不写例子咯...
最后通过dynamic 衍生出JObject (Json.Net)