C# 程式碼風格指南

原文:C# Coding Conventions (C# Programming Guide)

Naming Conventions

若句子太長,可以分段,結尾需為.

1
2
var currentPerformanceCounterCategory = new System.Diagnostics.
PerformanceCounterCategory();

Layout Conventions

  • 四空格縮排, tabs 需要存為空格
  • 一行一個Statement/Declaration
  • 連續的行中,第二行需要多一個縮排
  • 方法的宣告和屬性的宣告中至少需要隔一行
  • 在判斷式中加上括號
    • if ((val1 > val2) && (val1 > val3))

Commenting Conventions

  • 將程式和註解放在不同行
  • 註解需以大寫開頭,逗號結尾,與//間隔一個空格
1
2
// The following declaration creates a query. It does not run
// the query.

Language Guidelines

  • 使用字串插補(String interpolation)來連接短的字串
    • string displayName = $"{nameList[n].LastName}, {nameList[n].FirstName}";
  • 若要在迴圈中使用字串,使用StringBuilder
1
2
3
4
5
6
var phrase = "la";
var manyPhrases = new StringBuilder();
for (var i = 0; i < 10000; i++)
{
manyPhrases.Append(phrase);
}

Implicitly Typed Local Variables

  • 若變數的型別很明顯,使用隱式宣告
    • New, 型別轉換, 基本型別等
1
2
3
4
5
var var1 = "This is clearly a string.";
var var2 = 27;
// =======================
int var3 = Convert.ToInt32(Console.ReadLine());
int var4 = ExampleClass.ResultSoFar();
  • 可以在for中使用隱式宣告,但不要在foreach中使用隱式宣告

Arrays

1
2
3
4
5
6
7
8
// Preferred syntax. Note that you cannot use var here instead of string[].
string[] vowels1 = { "a", "e", "i", "o", "u" };
// If you use explicit instantiation, you can use var.
var vowels2 = new string[] { "a", "e", "i", "o", "u" };
// If you specify an array size, you must initialize the elements one at a time.
var vowels3 = new string[5];
vowels3[0] = "a";
vowels3[1] = "e";

Delegates(委託)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Define the type.
public delegate void Del(string message);

// Define a method that has a matching signature.
public static void DelMethod(string str)
{
Console.WriteLine("DelMethod argument: {0}", str);
}

// In the Main method, create an instance of Del.
// Preferred: Create an instance of Del by using condensed syntax.
Del exampleDel2 = DelMethod;
// The following declaration uses the full syntax.
Del exampleDel1 = new Del(DelMethod);

Using

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Method1: try-finally statement with Dispose
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
{
((IDisposable)font1).Dispose();
}
}

// Method2: Using statement.
using (Font font2 = new Font("Arial", 10.0f))
{
byte charset = font2.GdiCharSet;
}

&& and ||

  • && 取代 &, 用 || 取代 |
    • && 會 short-circult (即不可能是True時直接return False)
    • & 會判斷所有條件
1
2
3
4
5
6
7
8
if ((divisor != 0) && (dividend / divisor > 0))
{
Console.WriteLine("Quotient: {0}", dividend / divisor);
}
else
{
Console.WriteLine("Attempted division by 0 ends up here.");
}

New

  • 使用new的時候,使用var var instance1 = new ExampleClass();
  • 簡化Initialize
    • var instance3 = new ExampleClass { Name = "Desktop", ID = 37414, Location = "Redmond", Age = 2.3 };

事件

  • 使用lambda expression來產生一次性的event
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public Form2()
{
// You can use a lambda expression to define an event handler.
this.Click += (s, e) =>
{
MessageBox.Show(
((MouseEventArgs)e).Location.ToString());
};
}

// Using a lambda expression shortens the following traditional definition.
public Form1()
{
this.Click += new EventHandler(Form1_Click);
}

void Form1_Click(object sender, EventArgs e)
{
MessageBox.Show(((MouseEventArgs)e).Location.ToString());
}

Static

  • 用類別名取得static成員 ClassName.StaticMember
    • 不要用繼承的類別名,直接用定義static成員的類別

LINQ Queries

使用有意義的變數名

1
2
3
var seattleCustomers = from customer in customers
where customer.City == "Seattle"
select customer.Name;
  • 排列在from下方
  • 使用多個from取代join
1
2
3
4
5
// Use a compound from to access the inner sequence within each element.
var scoreQuery = from student in students
from score in student.Scores
where score > 90
select new { Last = student.LastName, score };