Dynamic 动态类型 和双问号??的使用
1.dynamic关键字用于声明一个动态对象,然后通过该动态对象去调用方法或读写属性。以前我们都是在运行时通过反射,Emit,CodeDom等技术来完成。创建一个dynamic类型的对象需要使用一个特殊的构建器叫ExpandoObject。
dynamic aehyok = new ExpandoObject(); aehyok.Name = "aehyok"; aehyok.Age = "24"; aehyok.Position = "ASP.NET"; Console.WriteLine("姓名:" + aehyok.Name + "年龄:" + aehyok.Age + aehyok.Position); Console.ReadKey();
通过控制台执行程序可以查看执行结果为:
2.通过动态类型来实现基于duck typing的泛型参数约束。
public static class Calculator { public static T Add<T>(T t1, T t2) { dynamic d1 = t1; dynamic d2 = t2; return (T)(d1 + d2); } }
那么通过调用
int i = Calculator.Add(1, 2); double d = Calculator.Add(1.1, 2.2); string s = Calculator.Add("abc", "def"); Console.WriteLine(i + " " + d + " " + s); Console.ReadKey();
执行后发现
除了运算符重载,对于普通的方法调用也是适用的。这种方法是一种动态duck typing的泛型参数约束机制,依赖于运行时的方法查找,与模板编译时的检查不同,它需要使用者保证传入的对象符合相应要求。
3.DynamicObject类都通过虚方法virtual去“实现”了接口中所有的方法,只要继承了这个类,读者可以根据需要“任意”动态覆盖你要的方法)。
public class DynamicAnimal : DynamicObject { public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { bool success = base.TryInvokeMember(binder, args, out result); //如果方法不存在,请将result 这个out参数赋值为null if (!success) { result = null; } //如果这个地方返回false 将会引发异常 return true; } }
继承此类被进行简单的实现。
接下来我们创建了两个类。
public class Duck : DynamicAnimal { public string Quack() { return "鸭子嘛,就是Quack吧。"; } } public class Human : DynamicAnimal { public string Talk() { return "人类是用Talk,而不是Quack"; } }
通过控制台应用程序进行调用
static void Main(string[] args) { var duck = new Duck(); var cow = new Human(); Console.WriteLine("鸭子是Quack"); Console.WriteLine(DoQuack(duck)); Console.WriteLine("人类是talk"); Console.WriteLine(DoQuack(cow)); Console.ReadKey(); } public static string DoQuack(dynamic animal) { string result = animal.Quack(); return result ?? "...人类当然不会鸭叫..."; } }
当然我们在下面定义了一个静态的方法传入dynamic类型,这里需要去调试就会明白。其中还有一个双问号
4.双问号的作用:
双问号(??)是一个单元运算符,那么其左右两边数据类型必须是相同类型或能隐形转换类型的。它表示的意思是,首先检测左边的值,若其为Null,那么整个表达式取值为右侧的值,否则为左侧的值。
参考以下链接:C#4.0和VS2010新特性(三)