clean code dotnet

2025-12-11 0 299

适用于.NET/.NET核心的清洁代码概念

如果您喜欢clean-code-dotnet项目,或者如果对您有所帮助,请为此存储库提供一颗星。这不仅将有助于加强我们的.NET社区,而且还可以提高世界各地.NET开发人员的清洁代码技能。非常感谢?

查看我的博客或在Twitter上打招呼!

目录

  • 适用于.NET/.NET核心的清洁代码概念
  • 目录
  • 介绍
  • 清洁代码.NET
    • 命名
    • 变量
    • 功能
    • 对象和数据结构
    • 课程
    • 坚硬的
    • 测试
    • 并发
    • 错误处理
    • 格式化
    • 评论
  • 其他干净的代码资源
  • 贡献者
  • 支持者
  • 赞助商
  • 执照

介绍

罗伯特·马丁 Robert C.这不是样式指南。它是在.NET/.NET Core中生产可读,可重复使用和可重构软件的指南。

并非必须严格遵循此处的所有原则,甚至更少会被普遍同意。这些是准则,仅此而已,但是它们是在多年的集体经验中由清洁代码的集体经验编纂的。

灵感来自清洁代码javaScript和Clean-ode-PHP列表。

清洁代码.NET

命名

避免使用坏名称

好名字允许许多开发人员使用代码。名称应反映其所做的事情并给出上下文。

坏的:

 int d ;

好的:

 int daySinceModification ;

⬆回到顶部

避免误导名称

命名变量以反映其使用的用途。

坏的:

 var dataFromDb = db . GetFromService ( ) . ToList ( ) ;

好的:

 var listOfEmployee = _employeeService . GetEmployees ( ) . ToList ( ) ;

⬆回到顶部

避免匈牙利符号

匈牙利符号重述了声明中已经存在的类型。这是毫无意义的,因为现代IDE将识别类型。

坏的:

 int iCounter ;
string strFullName ;
DateTime dModifiedDate ;

好的:

 int counter ;
string fullName ;
DateTime modifiedDate ;

匈牙利符号也不应在参数术中使用。

坏的:

 public bool IsShopOpen ( string pDay , int pAmount )
{
    // some logic
}

好的:

 public bool IsShopOpen ( string day , int amount )
{
    // some logic
}

⬆回到顶部

使用一致的资本化

资本化告诉您有关您的变量,功能等的很多信息。这些规则是主观的,因此您的团队可以选择他们想要的任何东西。关键是,无论您选择什么,都保持一致。

坏的:

 const int DAYS_IN_WEEK = 7 ;
const int daysInMonth = 30 ;

var songs = new List < string > { \'Back In Black\' , \'Stairway to Heaven\' , \'Hey Jude\' } ;
var Artists = new List < string > { \'ACDC\' , \'Led Zeppelin\' , \'The Beatles\' } ;

bool EraseDatabase ( ) { }
bool Restore_database ( ) { }

class animal { }
class Alpaca { }

好的:

 const int DaysInWeek = 7 ;
const int DaysInMonth = 30 ;

var songs = new List < string > { \'Back In Black\' , \'Stairway to Heaven\' , \'Hey Jude\' } ;
var artists = new List < string > { \'ACDC\' , \'Led Zeppelin\' , \'The Beatles\' } ;

bool EraseDatabase ( ) { }
bool RestoreDatabase ( ) { }

class Animal { }
class Alpaca { }

⬆回到顶部

使用明显的名称

当变量不可发音时,研究变量和函数的含义将需要时间。

坏的:

 public class Employee
{
    public Datetime sWorkDate { get ; set ; } // what the heck is this
    public Datetime modTime { get ; set ; } // same here
}

好的:

 public class Employee
{
    public Datetime StartWorkingDate { get ; set ; }
    public Datetime ModificationTime { get ; set ; }
}

⬆回到顶部

使用骆驼箱符号

使用骆驼箱表示法进行可变和方法参数。

坏的:

 var employeephone ;

public double CalculateSalary ( int workingdays , int workinghours )
{
    // some logic
}

好的:

 var employeePhone ;

public double CalculateSalary ( int workingDays , int workingHours )
{
    // some logic
}

⬆回到顶部

使用域名

阅读您的代码的人也是程序员。正确命名的事情将帮助每个人在同一页面上。我们不想花时间向所有人解释变量或函数的目的。

好的

 public class SingleObject
{
    // create an object of SingleObject
    private static SingleObject _instance = new SingleObject ( ) ;

    // make the constructor private so that this class cannot be instantiated
    private SingleObject ( ) { }

    // get the only object available
    public static SingleObject GetInstance ( )
    {
        return _instance ;
    }

    public string ShowMessage ( )
    {
        return \"Hello World!\" ;
    }
}

public static void main ( String [ ] args )
{
    // illegal construct
    // var object = new SingleObject();

    // Get the only object available
    var singletonObject = SingleObject . GetInstance ( ) ;

    // show the message
    singletonObject . ShowMessage ( ) ;
}

⬆回到顶部

变量

避免筑巢太深并提早返回

如果其他语句可以使代码难以遵循,太多了。明确胜于隐式

坏的:

 public bool IsShopOpen ( string day )
{
    if ( ! string . IsNullOrEmpty ( day ) )
    {
        day = day . ToLower ( ) ;
        if ( day == \"friday\" )
        {
            return true ;
        }
        else if ( day == \"saturday\" )
        {
            return true ;
        }
        else if ( day == \"sunday\" )
        {
            return true ;
        }
        else
        {
            return false ;
        }
    }
    else
    {
        return false ;
    }

}

好的:

 public bool IsShopOpen ( string day )
{
    if ( string . IsNullOrEmpty ( day ) )
    {
        return false ;
    }

    var openingDays = new [ ] { \"friday\" , \"saturday\" , \"sunday\" } ;
    return openingDays . Any ( d => d == day . ToLower ( ) ) ;
}

坏的:

 public long Fibonacci ( int n )
{
    if ( n < 50 )
    {
        if ( n != 0 )
        {
            if ( n != 1 )
            {
                return Fibonacci ( n - 1 ) + Fibonacci ( n - 2 ) ;
            }
            else
            {
                return 1 ;
            }
        }
        else
        {
            return 0 ;
        }
    }
    else
    {
        throw new System . Exception ( \"Not supported\" ) ;
    }
}

好的:

 public long Fibonacci ( int n )
{
    if ( n == 0 )
    {
        return 0 ;
    }

    if ( n == 1 )
    {
        return 1 ;
    }

    if ( n > 50 )
    {
        throw new System . Exception ( \"Not supported\" ) ;
    }

    return Fibonacci ( n - 1 ) + Fibonacci ( n - 2 ) ;
}

⬆回到顶部

避免心理映射

不要强迫代码的读者转换变量的含义。明确胜于隐式

坏的:

 var l = new [ ] { \"Austin\" , \"New York\" , \"San Francisco\" } ;

for ( var i = 0 ; i < l . Count ( ) ; i ++ )
{
    var li = l [ i ] ;
    DoStuff ( ) ;
    DoSomeOtherStuff ( ) ;

    // ...
    // ...
    // ...
    // Wait, what is `li` for again?
    Dispatch ( li ) ;
}

好的:

 var locations = new [ ] { \"Austin\" , \"New York\" , \"San Francisco\" } ;

foreach ( var location in locations )
{
    DoStuff ( ) ;
    DoSomeOtherStuff ( ) ;

    // ...
    // ...
    // ...
    Dispatch ( location ) ;
}

⬆回到顶部

避免魔术弦

魔术字符串是直接在应用程序代码中指定的字符串值,对应用程序的行为产生影响。通常,这样的字符串最终会在系统中重复,并且由于无法使用重构工具自动更新它们,因此当对某些字符串进行更改而不是其他字符串进行更改时,它们成为常见的错误来源。

坏的

 if ( userRole == \"Admin\" )
{
    // logic in here
}

好的

 const string ADMIN_ROLE = \"Admin\"
if ( userRole == ADMIN_ROLE )
{
    // logic in here
}

使用此功能,我们只需要在集中化的地方进行更改,而其他人则将对其进行调整。

⬆回到顶部

不要添加不必要的上下文

如果您的类/对象名称告诉您一些事情,请不要在变量名称中重复此操作。

坏的:

 public class Car
{
    public string CarMake { get ; set ; }
    public string CarModel { get ; set ; }
    public string CarColor { get ; set ; }

    //...
}

好的:

 public class Car
{
    public string Make { get ; set ; }
    public string Model { get ; set ; }
    public string Color { get ; set ; }

    //...
}

⬆回到顶部

使用有意义且明显的变量名称

坏的:

 var ymdstr = DateTime . UtcNow . ToString ( \"MMMM dd, yyyy\" ) ;

好的:

 var currentDate = DateTime . UtcNow . ToString ( \"MMMM dd, yyyy\" ) ;

⬆回到顶部

使用相同的词汇进行相同类型的变量

坏的:

 GetUserInfo ( ) ;
GetUserData ( ) ;
GetUserRecord ( ) ;
GetUserProfile ( ) ;

好的:

 GetUser ( ) ;

⬆回到顶部

使用可搜索的名称(第1部分)

我们将读取的代码超出我们将要写的代码。重要的是,我们编写的代码是可以读取且可搜索的。通过命名最终对于理解我们的计划有意义的变量,我们伤害了读者。使您的名字可搜索。

坏的:

 // What the heck is data for?
var data = new { Name = \"John\" , Age = 42 } ;

var stream1 = new MemoryStream ( ) ;
var ser1 = new DataContractJsonSerializer ( typeof ( object ) ) ;
ser1 . WriteObject ( stream1 , data ) ;

stream1 . Position = 0 ;
var sr1 = new StreamReader ( stream1 ) ;
Console . Write ( \"JSON form of Data object: \" ) ;
Console . WriteLine ( sr1 . ReadToEnd ( ) ) ;

好的:

 var person = new Person
{
    Name = \"John\" ,
    Age = 42
} ;

var stream2 = new MemoryStream ( ) ;
var ser2 = new DataContractJsonSerializer ( typeof ( Person ) ) ;
ser2 . WriteObject ( stream2 , data ) ;

stream2 . Position = 0 ;
var sr2 = new StreamReader ( stream2 ) ;
Console . Write ( \"JSON form of Data object: \" ) ;
Console . WriteLine ( sr2 . ReadToEnd ( ) ) ;

⬆回到顶部

使用可搜索的名称(第2部分)

坏的:

 var data = new { Name = \"John\" , Age = 42 , PersonAccess = 4 } ;

// What the heck is 4 for?
if ( data . PersonAccess == 4 )
{
    // do edit ...
}

好的:

 public enum PersonAccess : int
{
    ACCESS_READ = 1 ,
    ACCESS_CREATE = 2 ,
    ACCESS_UPDATE = 4 ,
    ACCESS_DELETE = 8
}

var person = new Person
{
    Name = \"John\" ,
    Age = 42 ,
    PersonAccess = PersonAccess . ACCESS_CREATE
} ;

if ( person . PersonAccess == PersonAccess . ACCESS_UPDATE )
{
    // do edit ...
}

⬆回到顶部

使用解释变量

坏的:

 const string Address = \"One Infinite Loop, Cupertino 95014\" ;
var cityZipCodeRegex = @\"/^[^,\\]+[,\\\\s]+(.+?)\\s*(\\d{5})?$/\" ;
var matches = Regex . Matches ( Address , cityZipCodeRegex ) ;
if ( matches [ 0 ] . Success == true && matches [ 1 ] . Success == true )
{
    SaveCityZipCode ( matches [ 0 ] . Value , matches [ 1 ] . Value ) ;
}

好的:

通过命名子图案降低对正则对等级的依赖。

 const string Address = \"One Infinite Loop, Cupertino 95014\" ;
var cityZipCodeWithGroupRegex = @\"/^[^,\\]+[,\\\\s]+(?<city>.+?)\\s*(?<zipCode>\\d{5})?$/\" ;
var matchesWithGroup = Regex . Match ( Address , cityZipCodeWithGroupRegex ) ;
var cityGroup = matchesWithGroup . Groups [ \"city\" ] ;
var zipCodeGroup = matchesWithGroup . Groups [ \"zipCode\" ] ;
if ( cityGroup . Success == true && zipCodeGroup . Success == true )
{
    SaveCityZipCode ( cityGroup . Value , zipCodeGroup . Value ) ;
}

⬆回到顶部

使用默认参数代替短路或有条件的参数

不好:

这不是很好,因为breweryName可能为NULL

该意见比以前的版本更容易理解,但是它可以更好地控制变量的价值。

 public void CreateMicrobrewery ( string name = null )
{
    var breweryName = ! string . IsNullOrEmpty ( name ) ? name : \"Hipster Brew Co.\" ;
    // ...
}

好的:

 public void CreateMicrobrewery ( string breweryName = \"Hipster Brew Co.\" )
{
    // ...
}

⬆回到顶部

功能

避免副作用

如果函数在占据值并返回其他值或值之外,则会产生副作用。副作用可能是写入文件,修改某些全局变量,或者将所有资金意外地接线到陌生人。

现在,您有时需要在程序中产生副作用。像上一个示例一样,您可能需要写入文件。您想做的是集中您在哪里做。没有写入特定文件的几个功能和类。有一项服务。一个也是一个。

要点是避免使用可以用任何结构的物体之间的对象之间共享状态,使用任何可以写入任何事物的可变数据类型,而不是集中副作用发生的位置。如果您可以做到这一点,那么您将比其他绝大多数程序员更快乐。

坏的:

 // Global variable referenced by following function.
// If we had another function that used this name, now it\'d be an array and it could break it.
var name = \"Ryan McDermott\" ;

public void SplitAndEnrichFullName ( )
{
var temp = name . Split ( \" \" ) ;
name = $ \"His first name is { temp [ 0 ] } , and his last name is { temp <span class=\"pl-k

下载源码

通过命令行克隆项目:

git clone https://github.com/thangchung/clean-code-dotnet.git

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 clean code dotnet https://www.zuozi.net/34205.html

systemd
上一篇: systemd
vexip ui
下一篇: vexip ui
常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务