MSDNexpress
The C# Language Specification does not define a coding standard. However, the guidelines in this topic are used by Microsoft to develop samples and documentation.api
C#語言規範不是用來規定編碼標準。然而,這些規範都是微軟在開發示例和文檔時遵循的。數組
Coding conventions serve the following purposes:安全
編碼規範是爲了達成下列目標:app
They create a consistent look to the code, so that readers can focus on content, not layout.編輯器
保證代碼外觀的一致性,讓讀者講精力集中在內容上,而不是形式。ide
They enable readers to understand the code more quickly by making assumptions based on previous experience.工具
經過良好的命名規範,使讀者能夠結合過往經驗快速理解代碼。oop
They facilitate copying, changing, and maintaining the code.佈局
經過規範簡化複製、更改和維護代碼。
They demonstrate C# best practices.
演示C#最佳實踐。
在不包括using指令的短示例中,使用命名空間限定。若是你知道命名空間默認導入項目中,則沒必要徹底限定來自該命名空間的名稱。 若是命名空間限定名太長,則能夠在點 (.) 後中斷限定名稱,以下例所示。
var currentPerformanceCounterCategory =newSystem.Diagnostics.
PerformanceCounterCategory();
你沒必要經過更改 Visual Studio 設計器工具建立的對象的名稱以使它們適合其餘準則。
Good layout uses formatting to emphasize the structure of your code and to make the code easier to read. Microsoft examples and samples conform to the following conventions:
好的代碼佈局用格式來強調代碼的結構並使代碼易於閱讀。 Microsoft 示例和樣本遵循如下規範:
Use the default Code Editor settings (smart indenting, four-character indents, tabs saved as spaces). For more information, see Options, Text Editor, C#, Formatting.
使用默認的代碼編輯器設置(智能縮進、4 字符縮進、製表符保存爲空格)。
Write only one statement per line.
每行只寫一條語句。
Write only one declaration per line.
每行只寫一個聲明。
If continuation lines are not indented automatically, indent them one tab stop (four spaces).
若是連續行未自動縮進,則縮進一個tab的寬度(4空格)。
Add at least one blank line between method definitions and property definitions.
每一個方法定義和每一個屬性定義間至少間隔一個空白行。
Use parentheses to make clauses in an expression apparent, as shown in the following code.
使用()號讓語句更清晰明瞭,以下代碼所示。
if((val1 > val2)&&(val1 > val3))
{
// Take appropriate action.
}
Place the comment on a separate line, not at the end of a line of code.
將註釋放在單獨的行上,而非代碼行的末尾。
Begin comment text with an uppercase letter.
註釋以大寫字母開頭。
End comment text with a period.
註釋以句號結尾。
Insert one space between the comment delimiter (//) and the comment text, as shown in the following example.
註釋分隔符
//
與註釋文本間空一個空格,以下例所示。
// The following declaration creates a query. It does not run
// the query.
不要在註釋周圍建立格式化的星號塊。
The following sections describe practices that the C# team follows to prepare code examples and samples.
如下各節介紹 C# 團隊編寫示例和樣本時遵循的作法。
+
operator to concatenate short strings, as shown in the following code.
使用「+」運算符來鏈接短字符串,以下代碼所示。
string displayName = nameList[n].LastName+", "+ nameList[n].FirstName;
在循環中拼接字符串,尤爲是有大量字符串時,請使用StringBuilder對象。
var phrase ="lalalalalalalalalalalalalalalalalalalalalalalalalalalalalala";
var manyPhrases =newStringBuilder();
for(var i =0; i <10000; i++)
{
manyPhrases.Append(phrase);
}
//Console.WriteLine("tra" + manyPhrases);
當變量類型明顯來自賦值的右側時,或者當具體類型不重要時,請對本地變量進行隱式類型化。
// When the type of a variable is clear from the context, use var
// in the declaration.
var var1 ="This is clearly a string.";
var var2 =27;
var var3 =Convert.ToInt32(Console.ReadLine());
當變量並不是明顯來自賦值右側時,請勿使用var。
// When the type of a variable is not clear from the context, use an
// explicit type.
int var4 =ExampleClass.ResultSoFar();
不用依靠變量名來判斷變量類型。這多是錯誤的。
// Naming the following variable inputInt is misleading.
// It is a string.
var inputInt =Console.ReadLine();
Console.WriteLine(inputInt);
Avoid the use of var
in place of dynamic.
避免用
var
來代替dynamic
。
Use implicit typing to determine the type of the loop variable in for and foreach loops.
for和foreach循環中推薦使用var。
The following example uses implicit typing in a for
statement.
下例for循環中使用隱式類型化。
var syllable ="ha";
var laugh ="";
for(var i =0; i <10; i++)
{
laugh += syllable;
Console.WriteLine(laugh);
}
The following example uses implicit typing in a foreach
statement.
下例foreach循環中使用隱式類型化。
foreach(var ch in laugh)
{
if(ch =='h')
Console.Write("H");
else
Console.Write(ch);
}
Console.WriteLine();
int
rather than unsigned types. The use of int
is common throughout C#, and it is easier to interact with other libraries when you use int
.
一般,使用 int 而不是無符號類型。 int 的使用在整個 C# 中都很常見,而且當你使用 int 時,更易於與其餘庫交互。
使用簡潔的語法來聲明數組。
// 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";
// And so on.
使用簡潔的語法來建立委託實例。
// First, in class Program, define the delegate type and a method that
// has a matching signature.
// 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);
對大多數異常處理使用 try-catch 語句。
staticstringGetValueFromArray(string[] array,int index)
{
try
{
return array[index];
}
catch(System.IndexOutOfRangeException ex)
{
Console.WriteLine("Index is out of range: {0}", index);
throw;
}
}
finally
block is a call to theDispose method, use a using
statement instead.
若是你異常處理 finally 塊中的惟一代碼是調用 Dispose 方法,請改用 using。
// This try-finally statement only calls Dispose in the finally block.
Font font1 =newFont("Arial",10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if(font1 !=null)
{
((IDisposable)font1).Dispose();
}
}
// You can do the same thing with a using statement.
using(Font font2 =newFont("Arial",10.0f))
{
byte charset = font2.GdiCharSet;
}
若要經過跳過沒必要要的比較來避免異常或提升性能,請在執行比較時使用 && 來代替 &,使用 || 來代替 | ,以下例所示。
Console.Write("Enter a dividend: ");
var dividend =Convert.ToInt32(Console.ReadLine());
Console.Write("Enter a divisor: ");
var divisor =Convert.ToInt32(Console.ReadLine());
// If the divisor is 0, the second clause in the following condition
// causes a run-time error. The && operator short circuits when the
// first expression is false. That is, it does not evaluate the
// second expression. The & operator evaluates both, and causes
// a run-time error when divisor is 0.
if((divisor !=0)&&(dividend / divisor >0))
{
Console.WriteLine("Quotient: {0}", dividend / divisor);
}
else
{
Console.WriteLine("Attempted division by 0 ends up here.");
}
使用簡潔的形式來實例化隱式類型,以下聲明所示。
var instance1 =newExampleClass();
The previous line is equivalent to the following declaration.
上一行等同於下面的聲明。
ExampleClass instance2 =newExampleClass();
使用對象初始化器簡化對象的建立。
// Object initializer.
var instance3 =newExampleClass{Name="Desktop", ID =37414,
Location="Redmond",Age=2.3};
// Default constructor and assignment statements.
var instance4 =newExampleClass();
instance4.Name="Desktop";
instance4.ID =37414;
instance4.Location="Redmond";
instance4.Age=2.3;
若是你正在定義一個你稍後不會刪除的事件處理程序,請使用Lambda表達式。
publicForm2()
{
// 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.
publicForm1()
{
this.Click+=newEventHandler(Form1_Click);
}
voidForm1_Click(object sender,EventArgs e)
{
MessageBox.Show(((MouseEventArgs)e).Location.ToString());
}
使用類名來調用靜態成員;類名.靜態成員名。這種作法經過指明靜態訪問使代碼更易讀。請勿使用派生類名來限定基類中定義的靜態成員。當那樣的代碼編譯時,代碼的可讀性會形成誤導,若未來你在派生類添加了同名的靜態成員,代碼可能會崩潰。
seattleCustomers
for customers who are located in Seattle.
查詢變量使用有意義的名稱。下面示例中使用
seattleCustomers
來表示住在Seattle(西雅圖)的客戶。
var seattleCustomers =
from cust in customers
where cust.City=="Seattle"
select cust.Name;
使用別名來確保匿名類型的屬性名都是Pascal命名法。
- Pascal(帕斯卡): 全部單詞首字母大寫。例如 WriteLine
- Camel(駝峯式): 第一個單詞首字母小寫,其餘單詞首字母大寫。例如 secondField
var localDistributors =
from customer in customers
join distributor in distributors on customer.City equals distributor.City
select new{Customer= customer,Distributor= distributor };
Name
and ID
in the result, rename them to clarify that Name
is the name of a customer, and ID
is the ID of a distributor.
若是結果中的屬性名模棱兩可,則對其重命名。例如,若是你的查詢返回了客戶名稱和分銷商ID,在返回結果不要將它們存爲
Name
和ID
,而是應該重命名以明確Name
指的是客戶的名稱,ID
指的是分銷商的ID。
var localDistributors2 =
from cust in customers
join dist in distributors on cust.City equals dist.City
select new{CustomerName= cust.Name,DistributorID= dist.ID };
聲明查詢變量和範圍變量時使用隱式類型。
var seattleCustomers =
from cust in customers
where cust.City=="Seattle"
select cust.Name;
Align query clauses under the from clause, as shown in the previous examples.
對其查詢語句和from子句,如上面的幾個例子所示。
Use where clauses before other query clauses to ensure that later query clauses operate on the reduced, filtered set of data.
在別的查詢語句以前使用where子句,來確保後面查詢的是篩選後的數據集。
var seattleCustomers2 =
from cust in customers
where cust.City=="Seattle"
orderby cust.Name
select cust;
from
clauses instead of a join clause to access inner collections. For example, a collection of Student
objects might each contain a collection of test scores. When the following query is executed, it returns each score that is over 90, along with the last name of the student who received the score.
使用多行
from
子句來代替Join子句訪問內部集合。例如,一個Student
集合裏,可能每一個學生都有一個考試分數集合。當執行下面的查詢時,它將返回90分以上的成績,並返回獲得該分數的學生的姓氏。
// 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 };
Follow the guidelines in Secure Coding Guidelines.
請遵循代碼安全維護指南中的準則。