在上一篇有關.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++;