zoukankan      html  css  js  c++  java
  • Effective C# 学习笔记(四十)使用Dynamic处理匿名类型参数

    有时你需要在你的方法的参数或返回值中使用匿名类型,而编译器不允许你这么使用匿名类型。你可以使用范型方法,或使用System.Object类型做参数来处理这种问题。但有时你又需要一些特定类型的行为特性来完成你的逻辑,而这个特定类型又不完全被你所掌握,这时你就需要使用Dynamic来处理这个问题。

     

    举个例子:

    你有一个逻辑是打印所有货物的物价清单,但是货物的存货信息、特殊订单信息以及第三方供货信息分别存储在三个不同的系统中。你可以通过API访问三个系统获取这些信息,但由于每个系统的货物的基类和接口及货物的nameprice属性名称也不尽相同。这时你可能会想到用到adapter pattern(适配器模式),但是这样的工作量是蛮大的。虽然这种模式使用静态类型,可以拥有很高的执行性能,但是对于新增加的货物类型的处理又得进行新的封装。

     

    这时你可以选择使用Dynamic来处理这种利用匿名类型来解决类型统一的问题。见如下代码:

    public static void WritePricingInformation(dynamic product)

    {

    Console.WriteLine("The price of one {0} is {1}", product.Name, product.Price);

    }

     

    上面的代码使用Dynamic关键字作为参数类型,声明货物为匿名类型。方法体中就可以随意调用货物的属性了。然后就是同一你不同系统中不同类型的属性名称。如下代码所示:

    var price = from n in Inventory

    where n.Cost > 20

    select new { n.Name, Price = n.Cost * 1.15M };//创建匿名类型对象,供WritePricingInformation方法使用

     

    对于那些已经拥有namePrice属性的类型来说你可以直接使用,如下代码所示:

    public class DiscountProduct

    {

    public static int NumberInInventory { get; set; }

    public double Price { get; set; }//注意:这里的price使用了double类型,而上面的投影使用的是decimal类型,这没有问题,dynamic会在运行时处理好这些不同

    public string Name { get; set; }

    public string ReasonForDiscount { get; set; }

    // other methods elided

    }

     

    注意:虽然dynamic带来了匿名类型参数方法方便,但是这样的转换会相对于静态类型更加耗费资源和运行时间,所以在可以使用静态类型的时候尽量使用静态类型。此外,你可以通过添加静态类型参数方法重载,来提供部分的程序运行性能,因为编译器会在运行时首先使用静态类型参数方法。如下代码所示:

    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);

    }

     

  • 相关阅读:
    在tomcat集群下利用redis实现单点登陆
    redis的入门篇---五种数据类型及基本操作
    redis的入门篇----启动和关闭
    window下nginx负载均衡简单配置-----权重的实现
    nginx的负载均衡配置,常用策略
    修改tomcat启动窗口的名称
    windows单机环境下配置tomcat集群
    maven的隔离部署
    什么是cap
    spring整合redis-----ShardedJedisPool实现
  • 原文地址:https://www.cnblogs.com/haokaibo/p/2122184.html
Copyright © 2011-2022 走看看