C#编码简单性之代码篇(如何编写简短的C#代码,随时更新)

简介:

以前写C++的时候曾经在自己网站上发表过一个编码“简单性”之文章,现在编写C#了才发现自己无意之间就会写下一些浪费屏幕的代码。

下面是自己编码中偶然发现的一些案例,欢迎中等水平的编程者参考。因为要积累案例,所以随时更新。


编码简单性的“心法”就是:只要屏幕上有任何两部分代码看上去相似,则一定有合并办法。

无论在微观还是宏观层面上这一点都适合。在02年的时候,我们曾在2小时内把一个程序员的4000多行的65个函数变为一个函数,相当于一个月的工作量被取代;04年则令人发指地发生了1个人用1.5年重新编写了13个人编写了9年的程序的事件。

因此,应随时关注代码中的“不简洁”现象,一旦放任其发生,软件将很难维护。


案例1 合并相似代码

以前遇到过的最极端的例子是:

 

switch (n)

{

case 1: return 1;

case 2: return 2;

case 3: return 3;

case 4: return 4;

case 5: return 5;

case 6: return 6;

default: return n;

}

这段代码其实相当于:return n;

这可不是个笑话,是01年一位还不错的同事编写的,原封未动就是这个样子6个整数。当我们指出来的时候,她忍不住笑了……人就这样,总有走火入魔的时候。

2011-07-31:今天不小心自己写的一段代码:

if (!result.Contains("true"))
{
_repSFC.GrantAuthorityToRole(authority, role, false);
}
if (result.Contains("true"))
{
_repSFC.GrantAuthorityToRole(authority, role, true);
}
其实就是:

_repSFC.GrantAuthorityToRole(authority, role, result.Contains("true"));
 

要发现它们,只需要牢记心法:只要屏幕上有任何两部分代码看上去相似,则一定有合并办法。

 

 


 

 

 

案例1.5 多用?+:语法

另一个小案例:

if (Misc == null)
return SFCCatches.LinkP2Cs.Where(i => i.P == p && i.C == c);
else
return SFCCatches.LinkP2Cs.Where(i => i.P == p && i.C == c && i.Misc == Misc);
改为:

return SFCCatches.LinkP2Cs.Where(i => i.P == p && i.C == c && (Misc == null ? true : i.Misc == Misc));
有时候感觉这种写法有点花哨,但是习惯以后,实际可读性要高得多,尤其如果单行代码挺长的时候。


案例2 推迟分支(请先看案例4)

这个长一些,原来的代码是aspx,在重构成Razor的时候发现可以简化。

<% foreach ( var techDebt in Model.TechDebts) 
{ %>
<% if (techDebt.IsOpen == true) 
{ %>
<div class = "Black">
<a href="/Agile/TechDebts/Edit/<%= techDebt.TechDebtID %>" target = "_blank" ><img title = "编辑" alt = "编辑" class = "icons" src="../../../../Resouces/Images/XXX/TechDebts/TechDebtOpening.png" /></a>
<%= techDebt.Type %>-<%= techDebt.Title %><br />
</div>
<%}
else
{ %>
<div class = "Gray">
<a href="/Agile/TechDebts/Edit/<%= techDebt.TechDebtID %>" target = "_blank" ><img title = "编辑" alt = "编辑" class = "icons" src="../../../../Resouces/Images/XXX/TechDebts/TechDebtsClosed.png" /></a>
<%= techDebt.Type %>-<%= techDebt.Title %><br />
</div>
<%} %>
<%} %>
变成Razor后等同于:

@foreach ( var techDebt in Model.TechDebts) 

string color = techDebt.IsOpen ? "Black" : "Gray"; //也可以放到下面的@color那里,但不太直观。
string img = techDebt.IsOpen ? "TechDebtOpening.png" : "TechDebtsClosed.png"; //同上。
<div class = @color>
<a href="/Agile/TechDebts/Edit/@techDebt.TechDebtID" target = "_blank" ><img title = "编辑" alt = "编辑" class = "icons" src="../../../../Resouces/Images/XXX/TechDebts/@img" /></a>
@techDebt.Type-@techDebt.Title<br />
</div>
}

19行代码变成9行。虽然看起来不起眼,但同比例放大10000倍看:把9万行代码编写成19万行,绝对是一个灾难。

同时注意color/img的处理,因为若把他们嵌入下面的代码中,代码会显得不直观,所以无需处理。毕竟看似多了2行“无用代码”,但他们与别处并无重复,理解起来也更简单。因此简单性是信息的简单性/无重复性,而不是简单地删除分号。


案例3

下面一段代码中,三个TD中的三个函数PrevViews/SameViews/NextViews破坏了简单的合并:

<td>
<ol id = "@Model.DropableID("PREV")" class = "dragable">
@foreach (var view in Model.PrevViews())
{
<li class = "black" id = "@view.DragableID()">
@Html.ImageLink("../../Resouces/Images/" + @view.Area + "/" + @view.Controller + "/" + @view.Action + "16.png",
view.Title, "imagelink", false, view.Action, view.Controller, view.Area, new { }, new { }, new { })
@(view.Title + "(" + view.Area + "/" + view.Controller + "/" + view.Action + ")")<br />
</li>
}
<br />
</ol>
</td>
<td>
<ol id = "@Model.DropableID("SAME")" class = "dragable">
@foreach (var view in SFCView.SameViews())
{
<li class = "black" id = "@view.DragableID()">
@Html.ImageLink("../../Resouces/Images/" + @view.Area + "/" + @view.Controller + "/" + @view.Action + "16.png",
view.Title, "imagelink", false, view.Action, view.Controller, view.Area, new { }, new { }, new { })
@(view.Title + "(" + view.Area + "/" + view.Controller + "/" + view.Action + ")")<br />
</li>
}
<br />
</ol>
</td>
<td>
<ol id = "@Model.DropableID("NEXT")" class = "dragable">
@foreach (var view in SFCView.NextViews())
{
<li class = "black" id = "@view.DragableID()">
@Html.ImageLink("../../Resouces/Images/" + @view.Area + "/" + @view.Controller + "/" + @view.Action + "16.png",
view.Title, "imagelink", false, view.Action, view.Controller, view.Area, new { }, new { }, new { })
@(view.Title + "(" + view.Area + "/" + view.Controller + "/" + view.Action + ")")<br />
</li>
}
<br />
</ol>
</td>
解决方法是使用Model传入三个IEnumerable:

<td>
<ol id = "@Model.DroppableID(SFCView.PREV)" class = "dragable">
@{Html.RenderPartial("_ViewList", Model.RelatedViews(SFCView.PREV));}
<br />
</ol>
</td>
<td>
<ol id = "@Model.DroppableID(SFCView.SAME)" class = "dragable">
@{Html.RenderPartial("_ViewList", Model.RelatedViews(SFCView.SAME));}
<br />
</ol>
</td>
<td>
<ol id = "@Model.DroppableID(SFCView.NEXT)" class = "dragable">
@{Html.RenderPartial("_ViewList", Model.RelatedViews(SFCView.NEXT));}
<br />
</ol>
</td>
这里就固定三种情况,基本上这样可读性和可维护性就可以了。

如果重复的次数更多,就要考虑把td一起搬进一个更大的循环体中。


案例4 2011-05-05:推迟分支

大致意思就是不要写:

if (...)

{

A();

B();

}

else

{

A();

C();

}

而是要写

A();

if (...)

{

B();

}

else

{

C();

}

心法是:任何两个地方看上去相似,就可以简化。技法是:相同部分放在分支前或后,不同部分才是分支。

这个案例看起来是愚蠢的,因为谁能看不出来呢,但实际结果不然,比如下面这段今天刚要写的代码(在一个url后面加上新的参数zoom=1):

url = (uri.Query.Count() == 0) ? uri.PathAndQuery + "?zoom=" + level : uri.PathAndQuery + "&zoom=" + level;

其实应该是:

uri.PathAndQuery + (uri.Query.Count() == 0 ? "?" : "&") + "zoom=" + level;

更隐蔽的是案例2。


本文转自火星人陈勇 51CTO博客,原文链接:http://blog.51cto.com/cheny/1100081


相关文章
|
1月前
|
缓存 C# Windows
C#程序如何编译成Native代码
【10月更文挑战第15天】在C#中,可以通过.NET Native和第三方工具(如Ngen.exe)将程序编译成Native代码,以提升性能和启动速度。.NET Native适用于UWP应用,而Ngen.exe则通过预编译托管程序集为本地机器代码来加速启动。不过,这些方法也可能增加编译时间和部署复杂度。
|
3月前
|
C# 开发者 Windows
在VB.NET项目中使用C#编写的代码
在VB.NET项目中使用C#编写的代码
57 0
|
1月前
|
C#
C# 图形验证码实现登录校验代码
C# 图形验证码实现登录校验代码
76 2
|
1月前
|
中间件 数据库连接 API
C#数据分表核心代码
C#数据分表核心代码
36 0
|
1月前
|
存储 C#
C#使用哈夫曼编码实现压缩与解压
C#使用哈夫曼编码实现压缩与解压
26 0
|
3月前
|
物联网 C# Windows
看看如何使用 C# 代码让 MQTT 进行完美通信
看看如何使用 C# 代码让 MQTT 进行完美通信
578 0
|
3月前
|
开发者 C# Android开发
Xamarin 与 .NET:解锁现代化移动应用开发的超级武器——深入探讨C#与.NET框架如何赋能跨平台应用,实现高效编码与卓越性能
【8月更文挑战第31天】Xamarin 与 .NET 的结合为开发者提供了强大的平台,用于构建现代化移动应用。通过 C# 和 .NET 框架,Xamarin 可以实现一次编写、多平台运行,覆盖 iOS、Android 和 Windows。这种方式不仅节省了开发时间和成本,还保证了应用的一致性和高质量。Xamarin 是一个开源框架,专为跨平台移动应用开发设计,允许使用 C# 语言和 .NET 核心库构建原生应用,并访问各平台特定功能。微软维护的 Xamarin 是 Visual Studio 生态系统的一部分,极大地提高了开发效率。
84 0
|
3月前
|
数据安全/隐私保护 C# UED
利用 Xamarin 开展企业级移动应用开发:从用户登录到客户管理,全面演示C#与Xamarin.Forms构建跨平台CRM应用的实战技巧与代码示例
【8月更文挑战第31天】利用 Xamarin 进行企业级移动应用开发能显著提升效率并确保高质量和高性能。Xamarin 的跨平台特性使得开发者可以通过单一的 C# 代码库构建 iOS、Android 和 Windows 应用,帮助企业快速推出产品并保持一致的用户体验。本文通过一个简单的 CRM 示例应用演示 Xamarin 的使用方法,并提供了具体的代码示例。该应用包括用户登录、客户列表显示和添加新客户等功能。此外,还介绍了如何增强应用的安全性、数据持久化、性能优化及可扩展性,从而构建出功能全面且体验良好的移动应用。
52 0
|
3月前
|
前端开发 开发者 Apache
揭秘Apache Wicket项目结构:如何打造Web应用的钢铁长城,告别混乱代码!
【8月更文挑战第31天】Apache Wicket凭借其组件化设计深受Java Web开发者青睐。本文详细解析了Wicket项目结构,帮助你构建可维护的大型Web应用。通过示例展示了如何使用Maven管理依赖,并组织页面、组件及业务逻辑,确保代码清晰易懂。Wicket提供的页面继承、组件重用等功能进一步增强了项目的可维护性和扩展性。掌握这些技巧,能够显著提升开发效率,构建更稳定的Web应用。
104 0
|
3月前
|
前端开发 程序员 API
从后端到前端的无缝切换:一名C#程序员如何借助Blazor技术实现全栈开发的梦想——深入解析Blazor框架下的Web应用构建之旅,附带实战代码示例与项目配置技巧揭露
【8月更文挑战第31天】本文通过详细步骤和代码示例,介绍了如何利用 Blazor 构建全栈 Web 应用。从创建新的 Blazor WebAssembly 项目开始,逐步演示了前后端分离的服务架构设计,包括 REST API 的设置及 Blazor 组件的数据展示。通过整合前后端逻辑,C# 开发者能够在统一环境中实现高效且一致的全栈开发。Blazor 的引入不仅简化了 Web 应用开发流程,还为习惯于后端开发的程序员提供了进入前端世界的桥梁。
338 0