zoukankan      html  css  js  c++  java
  • More Effective C# Item9 :使用泛型元组代替out和ref参数

        如果我们在进行设计时,需要针对一个方法返回多个结果,通常情况下,我们会使用ref或者out参数。同时,我们还是使用泛型元组来返回多个不相关的值。

        我们来看下面的代码,首先定义一个具有继承关系的结构。

    代码
    1 publicclass Person
    2 {
    3 privatereadonlystring m_strName;
    4 publicstring Name
    5 {
    6 get { return m_strName; }
    7 }
    8
    9 public Person(string name)
    10 {
    11 m_strName = name;
    12 }
    13
    14 publicoverridestring ToString()
    15 {
    16 returnstring.Format("Name:{0}", m_strName);
    17 }
    18 }
    19
    20 publicclass Employee : Person
    21 {
    22 privatereadonly Decimal m_deSalary;
    23 public Decimal Salary
    24 {
    25 get { return m_deSalary; }
    26 }
    27
    28 public Employee(string name, decimal salary)
    29 : base(name)
    30 {
    31 m_deSalary = salary;
    32 }
    33
    34 publicoverridestring ToString()
    35 {
    36 returnstring.Format("Name:{0}, Salary:{1}", base.Name, m_deSalary);
    37 }
    38 }

        下面是测试代码。

    代码
    1 privatestaticvoid Test()
    2 {
    3 Employee emp =new Employee("Wing", 1000);
    4 ChangeName(ref emp, "UnKnown", 2000);
    5
    6 Person person =new Person("Wing");
    7 ChangeName(ref person, "UnKnown");
    8 }
    9
    10 privatestaticvoid ChangeName(ref Employee emp, string newName, Decimal newSalary)
    11 {
    12 Console.WriteLine(emp);
    13 emp =new Employee(newName, newSalary);
    14 Console.WriteLine(emp);
    15 }
    16
    17 privatestaticvoid ChangeName(ref Person person, string newName)
    18 {
    19 Console.WriteLine(person);
    20 person =new Person(newName);
    21 Console.WriteLine(person);
    22 }

        我们来看一下使用ref和out时的限制,首先,使用ref参数,很难创建不可变的对象;其次,使用ref参数,很难实现多态,因为ref参数不支持隐式类型转换。例如上面代码中,我们需要定义两个ChangName方法,针对ChangName(Person person)时,传入Employee类型的对象,否则,就会报编译错误。

        其实ref参数和返回值的区别也在此,方法的返回值是可以支持隐式类型转换的,可以将返回值设置为父类型,然后在实际运行时,返回子类型。

        那么如何避免使用ref参数呢,我们可以使用元组,即Tuple。

        我们可以看以下的代码。

    1 private static Tuple<string, Decimal> GetEmpInfo(Employee emp)
    2 {
    3     return new Tuple<string, Decimal>(emp.Name, emp.Salary);
    4 }

        或许上面的代码只是重新调整了一下方法的签名,但是当你逐渐熟悉使用函数式编程结构时,你就会发现这个技术的重要性。接受out或者ref参数的方法无法与其他方法良好的组合在一起,而返回单一值(无论多复杂)的方法则能很好的进行组合。

        ref和out参数表明方法中可以创建出符合声明类型的对象,多态表明派生类总是可以代替基类。不过当方法中需要创建出返回值对象时,上述说法还包含了一些新的含义。当调用代码期待基类对象时,很多情况下方法中都会创建出派生类型对象。总的来说,上述两条规则意味着,out和ref参数无法真正的使用到多态,若是改为使用泛型元组返回多个值,那么你的算法逻辑会更易于使用。

        
    作者:李潘
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Direct3D光与材质的颜色值
    Direct中灯光的注意事项
    DirectInput:poll轮询理解
    GetAsyncKeyState函数返回值
    关于PeekMessage中hwnd参数
    VS链接MySql需注意的一些问题(C/C++)
    Windows配置:环境变量是个什么玩意儿?
    项目中ofstream 打开当前文件夹下内容失败原因
    hdoj--2073--无限的路(数学规律)
    hdoj--1205--吃糖果(规律)
  • 原文地址:https://www.cnblogs.com/wing011203/p/1758527.html
Copyright © 2011-2022 走看看