在上一篇有关.Net 轻量 ORM Dapper 的介绍中咱们提出了两个疑问,其中之一就是怎么让 Dapper 查询传参可变的问题,固然这里主要说是个数可变。这里咱们就介绍C#4.0的新特性之一—— dynamic 。javascript
public static void Show(string str1="str1",string str2="str2") { Console.WriteLine(str1 + str2); }
Show(str2:"msg");运行结果:str1msg。当你的方法有多个同一类型的可选参数(optional parameters)时,命名参数(Named parameters)特别有用。若是不用命名参数,编译器会把传参赋给第一个符合类型的参数,运行结果就会是:msgstr2。
dynamic person = new System.Dynamic.ExpandoObject(); person.Name = "cary"; person.Age = 25; person.ShowDescription = new Func<string>(() => person.Name + person.Age); Console.WriteLine(person.Name+person.Age+person.ShowDescription()); Console.ReadLine();
dynamic a = "test"; a++;这就要求咱们在使用 dynamic 关键字时要特别当心。
static class Calculator { public static T Add<T>(T t1, T t2) { dynamic d1 = t1; dynamic d2 = t2; return (T)(d1 + d2); } } public static void Main(string[] args){ 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); }做者在文中指出 C#代码是为了经过动态类型来实现基于duck typing的泛型参数约束。ExpandoObject 是C#支持Duck Type的根本缘由。在Visual Studio 2010 中咱们能够看到该类的成员列表,截图以下:
function tryInvokeMember(obj) { if (obj && typeof obj.ourMethod === "function") { return obj.ourMethod(); } alert('未找到!'); return null; } var ourObj1 = {}; ourObj1.Method = function () { alert('111'); }; var ourObj2 = {}; ourObj2.ourMethod = function () { alert('已经找到ourMethod而且执行'); }; tryInvokeMember(ourObj1); tryInvokeMember(ourObj2);你们读完这段js代码后应该会明白为何我要重点讨论C#4.0中的DynamicObject了吧?真正的目的就是:在DuckType 类(鸭子) 方法(鸭子叫)执行以前,咱们要判断对象的类是不是具有鸭子叫的功能?若是不具有就不该该执行,不然程序势必会抛出异常。C#中如何实现呢?步骤以下:
<strong> </strong>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"; } }
public static string DoQuack(dynamic animal) { string result = animal.Quack(); return result ?? "...人类固然不会鸭叫..."; }
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(); }
var a=1; object a=1; dynamic c=1;以及
var a = new string[]{"1"}; object b = new string[]{"1"}; dynamic c = new string[]{"1"};比较一下有助于记忆。
var a = 1; a = "Test";object之因此可以被赋值为任意类型的缘由,其实都知道,由于全部的类型都派生自object. 因此它能够赋值为任何类型:
object a = 1; a = "Test";dynamic是C#引入的新类型,它的特色是申明为dynamic类型的变量,不是在编译时候肯定实际类型的, 而是在运行时。因此下面的代码是可以经过编译的,可是会在运行时报错:
dynamic a = "test"; a++;上面代码内部处理的过程是怎样的呢?首先, dynamic类型赋值为字符串"test", 运行++操做的时候,.net会去寻找当前的赋值类型string中是否支持++操做,发现不支持,出现异常。因此,若是这样修改一下,就可让代码正常运行起来。
dynamic a = "test"; a = 1; a++;