<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 原則40:使用動態接收匿名類型參數 **By D.S.Qiu** **尊重他人的勞動,支持原創,轉載請注明出處:[http://dsqiu.iteye.com](http://dsqiu.iteye.com)** 匿名參數的一個缺陷是你不能輕易讓一個方法使用其作為參數或返回值。因為編譯器產生的匿名類型,你不能用來作為方法的參數或返回值。這個問題的任何解決方案都是與局限的。你可以使用匿名類型作為泛型類型參數,或者傳給參數為 System.Object 的方法。這些都不會覺得特別滿意。泛型方法只能假設類型定義在 System.Object 的功能。 System.Object 同樣也有局限。當然,有些時候,你會發現確實需要對一個實際的行為的類命名。本節主要討論當你需要使用不同的匿名類型,即他們有相同命名的屬性但不是你應用的核心部分,而且你不想創建新的命名類型時,你需要做什么。 動態類型可以讓你克服這個限制。動態是在運行時綁定并且使編譯器為可能的運行時類型生成必需的代碼。 假設你需要打印一個價格表的信息。進一步假設你的價格表,可以從多個數據源的產生。你可能有一個存儲倉庫的數據庫,另一個存儲特別訂單,并且還有一個是存儲通過第三方供應商出售的價格。因為它們都是不同的系統,它們可能是不同商品的抽象。這些不同的抽象可能沒有相同名字的屬性,而且它們沒有共同的基類或實現同一個接口。經典的解放方案是實現一個適配器模式(查看 Design Patterns, Gamma, Helm, Johnson, &Vlisside, pp.139-142)為每個產品進行抽象,并轉換每個對象為一致的類型。這有相當多的工作,你要為每個新產品的抽象添加適配器。而且,適配器模式在靜態類型系統會有更好的性能。 另一個,輕量的解決方案是是用動態創建方法,傳入有任何價格信息的類型: ``` public static void WritePricingInformation(dynamic product) { Console.WriteLine("The price of one {0} is {1}", product.Name, product.Price); } ``` 你可以創建匿名類型,通過在你的價格方法中匹配屬性,就可以從數據源得到價格信息: ``` var price = from n in Inventory where n.Cost > 20 select new { n.Name, Price = n.Cost * 1.15M }; ``` 你任何項目的動態方法創建匿名類型都要包含必需的屬性。只要有命名為“ Price ”和“ Name ”的屬性,WritePricingInformation 方法就可以完成這個工作。 當然,你還可以使用匿名類的其他屬性。只要屬性包含在價格信息中,你就是對的: ``` var orderInfo = from n in Ordered select new { n.Name, Price = n.Cost * 1.15M, ShippingCost = n.Cost / 10M }; ``` 普通的命名的 C# 對象可以在動態中使用。這說明你的價格信息方法可以使用含有正確命名的屬性的具體的類: ``` public class DiscountProduct { public static int NumberInInventory { get; set; } public double Price { get; set; } public string Name { get; set; } public string ReasonForDiscount { get; set; } // other methods elided } ``` 你可能主要到 DiscountProduct 的 Price 屬性的類型是 double 而之前的匿名類型的 Price 的類型是 decimal 。這樣也是可以的。 WritePricingInformation 使用動態靜態類型,所以它會在運行時確定是否正確。當然,如果 DiscountProduct 繼承自 Product 類,并且 Product 類包含 Name 和 Price 屬性,也是可以工作的。 上面的代碼可能會讓你很容易相信我比我實際中更主張使用動態。動態調用的確是解決這個問題的好方法,但不要過度使用。動態調用意味著你需要支付額外的開銷。當你需要時,這個開銷是值得的,但是當你可以避免它,你就應該避免。 你不得不在靜態和動態調用之間做出選擇。你可以創建 WritePricingInformation() 方法的重寫,就可以具體到你對象模型的每個產品類: ``` public class Product { public decimal Cost { get; set; } public string Name { get; set; } public decimal Price { get { return Cost * 1.15M; } } } // Derived Product class: public class SpecialProduct : Product { public string ReasonOnSpecial { get; set; } // other methods elided } // elsewhere public static void WritePricingInformation(dynamic product) { Console.WriteLine("The price of one {0} is {1}", product.Name, product.Price); } public static void WritePricingInformation(Product product) { Console.WriteLine("In type safe version"); Console.WriteLine("The price of one {0} is {1}",product.Name, product.Price); } ``` 編譯器會針對 Product 或 SpecialProduct 的對象(或者對象模型中任何其他子類的對象)使用具體的版本。對于其他類型,編譯器靜態類型版本當做動態使用。這包括匿名類型。動態綁定器在內部會將每個使用的方法緩存起來。類似調用 WritePricingInformation() 一樣反復調用同一匿名類型的情況,可以減少開銷。一旦方法在第一次調用綁定,就會可以在后續的調用重用。這是零開銷,但動態的實現應該盡可能最小化使用動態的開銷。 你可能懷疑為什么這些方法不能是擴展方法,這樣就可以看起來是匿名類型的成員。的確,那是很不錯的想法,但這在 C# 是不合法的。你不允許創建多態對象的擴展方法。 你可以利用動態創建使用匿名類型的方法。要像刺激的調味品一樣少用這項技術。如果你發現你為了使用匿名類型使用動態調用創建很多方法,這很明顯的跡象,你需要創建具體的類型來表示這些概念。這更容易日后維護,你也會得到類型系統和編譯器的更多支持。然而,當你需要一到兩個使用匿名類型的實用方法,動態調用是創建這個行為的簡單的方法。 小結: 哎,作者一再強調動態耗時,但是一直沒有具體指出哪些過程為什么耗時! 歡迎各種不爽,各種噴,寫這個純屬個人愛好,秉持”分享“之德! 有關本書的其他章節翻譯請[點擊查看](/category/297763),轉載請注明出處,尊重原創! 如果您對D.S.Qiu有任何建議或意見可以在文章后面評論,或者發郵件(gd.s.qiu@gmail.com)交流,您的鼓勵和支持是我前進的動力,希望能有更多更好的分享。 轉載請在**文首**注明出處:[http://dsqiu.iteye.com/blog/2090600](/blog/2090600) 更多精彩請關注D.S.Qiu的博客和微博(ID:靜水逐風)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看