zoukankan      html  css  js  c++  java
  • 一起谈.NET技术,C#中使用#region指令的一些想法 狼人:

      这篇文章我将不会去介绍如何使用#region指令。因为每个C#开发人员都应该见过和使用过#region指令的。这篇文章将讨论如何在代码中正确的使用它。使用#region就是将一些有关联的代码组织在一起,然后折叠起来。这样你就在一个函数中看不到很长的令人头痛的代码段。例如:

    public void DoSomething()
    {
    bool shouldIDoSomething;

    #region Decide if I should do something

    if(needToDoSomething && haventDoneSomethingThisDay)
    shouldIDoSomething
    = true;
    else
    {
    // do some other logic to decide and set shouldIDoSomething to some value
    }

    #endregion

    if(shouldIDoSomething)
    {
    done
    ++;
    }
    }

      当然这段代码很简单。在实际项目中,你可能看到上百行甚至更多的代码在一个#region中。如果把它折叠起来。看起来就会很整洁。是吧?

    public void DoSomething()
    {
    bool shouldIDoSomething;

    [Decide
    if I should do something]

    if(shouldIDoSomething)
    {
    done
    ++;
    }
    }

      只是把一些代码和一些变量组合起来放在#region中。如果你在仔细想想,其实我们相当与创建了一个新的函数,只是将这些方法内置到当前函数中。一个函数只做单一的一件事情,这是Clean Code这本书的一个原则。为什么我们不把它提取为一个函数呢,这样一来,一个函数就只做一件事情了。

    public void DoSomething()
    {
    if(ShouldIDoSomething())
    {
    done
    ++;
    }
    }

    private bool ShouldIDoSomething()
    {
    if(needToDoSomething && haventDoneSomethingThisDay)
    shouldIDoSomething
    = true;
    else
    {
    // do some other logic to decide and set shouldIDoSomething to some value
    }
    }

      上面看起来就清楚很多,因为我们降低了之前的DoSomething函数的复杂度。两个函数可以分开测试,确保没有逻辑错误。
      小段总结1:  #region 不适合在大方法中使用,当你在一个方法中使用#region 的时候,停下来想想你刚刚写了什么代码?大多数时候,你可以将这些代码段独立成一个函数。

      看看下面这段非常漂亮的代码:

    #region Get Customer

    public void GetCustomer()
    {
    // code to get the customer
    }

    #endregion

    #region Save Customer

    public void SaveCustomer()
    {
    // code to save the customer
    }

    #endregion

      将它折叠之后,变成下面这样:

    [Get Customer]

    [Save Customer]

      这样做很容易阅读吗?这样做的目的是什么,我不明白?代码折叠就会变得更好?我觉得这样做只会让代码更难以阅读,因为你每次要看region中的代码,你都要展开一次。

      小段总结2:不要因为你能,你就使用#region 。

      再看下面这个例子

    public class PriceCalculator
    {
    public decimal CalculatePrice()
    {
    decimal price = 100m;
    decimal discount = CalculateDiscount();
    return price * (1m - discount));
    }

    #region Discount Calculation

    private void CalculateDiscount()
    {
    decimal discount = 0m;

    if(CanApplyDiscount())
    discount
    = 0.05m;

    return discount;
    }

    private void CanApplyDiscount()
    {
    // some logic, other method calls
    }

    // some other discount calculation methods
    ...

    #endregion
    }

      如果你将这个例子和本文中的第一个例子做下比较,你可能会看到它们的共同点。他们是相同的,不过一个是在类中,一个是在函数中,层级不同而已。这里在提一个原则:单一职责原则,一个类应该只有一个职责。看上面的类,你可以很容易看出它有两个职责:价格计算和折扣计算。折扣计算的方法被放到一个#region中。同样,可以将它们提取出来做为一个新类。

      小段总结3:可以将一组相关的函数提取到一个职责单一的新类中。

      那我们到底怎么使用 #region 呢。将东西用它来分组,它是非常有用的。在我写的类中或多或少有几个#region,用来对类中不同的结构进行分组。比如: fields, properties, methods, events, types等。如果你打开我写的类文件,你会看到结构如下:

    public class SomeClass
    {
    [Events]

    [Fields]

    [Properties]

    [Methods]
    }

      总的来说:我将#region看成能控制阅读源代码的复杂度的一种方式。因为你可以将一些相关的代码放在一个区域(#region)里面。但是,这不是你随便就创建新方法或者新类的借口。其实Region并不能消除复杂度,它只是在你阅读代码的时候,隐藏了部分代码。你必须通过写出小巧,清晰,重点突出的方法和类,才能控制代码的复杂度。当你做到这些的时候,你甚至会发现#region是不必要的。

      本文翻译:About #region preprocessor directive

  • 相关阅读:
    【转】Java抽象类与接口的区别
    【转】java方法参数传递方式--按值传递、引用传递
    关联mysql失败_Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezon'
    分词器的安装与使用
    Mysql、ES 数据同步
    ES、kibana安装及交互操作
    tl-wr742n 怎么设置dns
    tl-wr742n无线路由器怎么设置
    PowerMock学习(十一)之Mock private methods的使用
    PowerMock学习(十)之Mock spy的使用
  • 原文地址:https://www.cnblogs.com/waw/p/2162681.html
Copyright © 2011-2022 走看看