Kumpulan pedoman yang sebagian besar masuk akal dan praktik terbaik untuk menulis kode C# yang bersih, dapat dibaca, dapat dimengerti, dan dapat dipelihara.
var kapan pun sesuai dan mungkinTujuan: Keterbacaan dan kebersihan yang lebih baik
BAGUS
var httpClient = new HttpClient ( ) ;BURUK
HttpClient httpClient = new HttpClient ( ) ; Tujuan: Keterbacaan dan kebersihan yang lebih baik
BAGUS
var user = new User
{
Username = "admin" ,
Age = 31
} ;BURUK
var user = new User ( ) ;
user . Username = "admin" ;
user . Age = 31 ; string.FormatTUJUAN: Keterbacaan dan semantik yang lebih baik
BAGUS
var url = "http://localhost/api" ;
var resource = "users" ;
var path = $ " { url } / { resource } " ;BURUK
var url = "http://localhost/api" ;
var resource = "users" ;
var path = string . Format ( "{0}/{1}" , url , resource ) ;Tujuan: Tidak perlu melarikan diri dari karakter backslash
BAGUS
var path = @"C:UsersAdministratorDocuments" ;BURUK
var path = "C: \ Users \ Administrator \ Documents" ;TUJUAN: Refactoring bisa menjadi mimpi buruk ketika literal string didistribusikan di mana -mana beberapa kali
BAGUS
const string error = "user_not_found" ;
Log . Error ( error ) ;
return BadRequest ( error ) ;BURUK
Log . Error ( "user_not_found" ) ;
return BadRequest ( "user_not_found" ) ; xyz . Itu hanya konyol.Tujuan: Memendekkan nama variabel tidak menambah nilai apa pun, bahkan membuat kode menjadi lebih sulit untuk dibaca dan dipahami
BAGUS
// Nice
var validationResult = validator . Validate ( ) ;
// Nice
var stringBuilder = new StringBuilder ( ) ;
// Nice
const string directorySeparator = "/" ;BURUK
//
var res = validator . Validate ( ) ;
//
var sbd = new StringBuilder ( ) ;
// Seriously?
const string dsep = "/" ;Tujuan: Membuat kode sangat mudah dibaca, dipelihara dan dikerjakan
BAGUS
// The purpose of this class can be easily inferred
public class OrderManager
{
// Using "Is" or "Has" as prefix clearly indicates that a method returns a boolean value
public bool IsFulfilled ( Order order )
{
}
public bool HasPositions ( Order order )
{
}
// Using a verb clearly indicates that a method performs some action
public void ProcessOrder ( Order order )
{
}
public void CancelOrder ( Order order )
{
}
}BURUK
// Purpose of this class can not be easily inferred
public class OrderHelper
{
// Unclear
public bool Fulfilled ( Order order )
{
}
// Unclear => users would likely expect a method that retrieves the positions of the order due to the verb "Get"
public bool GetPositions ( Order order )
{
}
// Unclear
public void Order ( Order order )
{
}
// Unclear
public void StopOrder ( Order order )
{
}
}Tujuan: Membuat kode tidak perlu lebih lama dan lebih sulit dibaca dan dipahami
BAGUS
// Clearly an interface
public interface IOrderManager { }
// Clearly a list of orders
private IList < Order > orders ;BURUK
// Clearly an interface => no "Interface" postfix necessary
public interface IOrderManagerInterface { }
// Clearly a list of oders => no "List" postfix necessary
private IList < Order > orderList ;TUJUAN: Praktik ini menunjukkan bahwa komentar dapat menjadi ketinggalan zaman dengan sangat mudah dan cepat saat basis kode tumbuh dan berkembang. Memiliki basis kode yang jelas berkontribusi pada pemeliharaan yang lebih baik dan mengurangi kebutuhan untuk menulis dan mempertahankan komentar yang tidak perlu. (Ini tidak berarti bahwa komentar menulis sudah usang.)
BAGUS
public class OrderManager
{
public void ProcessOrder ( Order order )
{
var items = order . GetItems ( ) ;
foreach ( var item in items )
{
var availability = item . GetAvailability ( ) ;
}
}
}BURUK
public class OrderManager
{
public void ExecuteOrder ( Order order )
{
// Get all available items from the order
var data = order . GetData ( ) ;
foreach ( var x in data )
{
// Determine the availability of the item
var available = item . CheckAvailability ( ) ;
}
}
}Tujuan: Konsisten dengan .NET Framework dan lebih mudah dibaca
BAGUS
public class JsonParser { }BURUK
public class JSONParser { } TUJUAN: enum s selalu ditangani secara individual. Misalnya EmploymentType.FullTime jauh lebih bersih daripada EmploymentTypes.FullTime . Selain itu, kelas selalu mewakili satu instance dari suatu objek, misalnya User individu. Pengecualian: Bit Field Enums
BAGUS
public enum EmploymentType
{
FullTime ,
PartTime
}
public class User
{
}BURUK
public enum EmploymentTypes
{
FullTime ,
PartTime
}
public class Users
{
} Tujuan: Gula Sintaksis ¯ (ツ) /¯
BAGUS
public class User
{
public string Username { get ; }
public int Age { get ; }
public string DisplayName => $ " { Username } ( { Age } )" ;
public User ( string username , int age )
{
Username = username ;
Age = age ;
}
}BURUK
public class User
{
public string Username { get ; }
public int Age { get ; }
public string DisplayName
{
get
{
return $ " { Username } ( { Age } )" ;
}
}
public User ( string username , int age )
{
Username = username ;
Age = age ;
}
} Tujuan: Kesadaran yang lebih baik tentang apa yang salah. Memungkinkan lebih presisi selama analisis logging dan kesalahan.
BAGUS
try
{
System . IO . File . Open ( path ) ;
}
catch ( FileNotFoundException ex )
{
// Specific
}
catch ( IOException ex )
{
// Specific
}
catch ( Exception ex )
{
// Default
}BURUK
try
{
System . IO . File . Open ( path ) ;
}
catch ( Exception ex )
{
// SOMETHING went wrong
}Exception sendiri Tujuan: Praktek yang sangat buruk. Exception hanya boleh dilemparkan oleh .NET Framework.
BAGUS
public void ProcessOrder ( Order order )
{
if ( order == null )
{
throw new ArgumentNullException ( nameof ( order ) ) ;
}
}BURUK
public void ProcessOrder ( Order order )
{
if ( order == null )
{
throw new Exception ( "Order is null." ) ;
}
} Tujuan: Keterbacaan yang lebih baik
BAGUS
private string _username ;BURUK
private string mUsername__ ;
// OR
private string username ;
// OR
private string username_ ; Tujuan: Keterbacaan yang Lebih Baik, Menghemat Ruang
BAGUS
public class JsonParser
{
private readonly string _json ;
public JsonParser ( string json )
{
_json = json ;
}
}BURUK
public class JsonParser
{
private readonly string _json ;
public JsonParser ( string json )
{
_json = json ;
}
} Tujuan: Mencegah properti dari tidak sengaja diubah dari tempat lain, prediksi yang lebih baik dari perilaku aplikasi
BAGUS
public class JsonParser
{
public string Json { get ; }
public JsonParser ( string json )
{
Json = json ;
}
}BURUK
public class JsonParser
{
public string Json { get ; set ; }
public JsonParser ( string json )
{
Json = json ;
}
}TUJUAN: Mencegah pengumpulan dari diubah dari tempat lain, prediksi yang lebih baik dari perilaku aplikasi
BAGUS
public class KeywordProvider
{
public IReadOnlyCollection < string > Keywords { get ; }
public KeywordProvider ( )
{
Keywords = new ReadOnlyCollection < string > ( new List < string >
{
"public" ,
"string"
} ) ;
}
}BURUK
public class KeywordProvider
{
public IList < string > Keywords { get ; }
public KeywordProvider ( )
{
Keywords = new List < string >
{
"public" ,
"string"
} ;
}
} using blok Tujuan: Sumber daya secara otomatis dibuang saat blok using selesai
BAGUS
using ( var connection = new SqlConnection ( connectionString ) )
{
}BURUK
try
{
var connection = new SqlConnection ( connectionString ) ;
}
finally
{
connection . Close ( ) ;
connection . Dispose ( ) ;
} Tujuan: Keterbacaan yang lebih baik, pemeliharaan yang lebih mudah saat jalur lain diperlukan di dalam kondisi
BAGUS
if ( user . IsElevated )
{
// Do something
}BURUK
if ( user . IsElevated )
// Do somethingTUJUAN: Sehingga Anda mengetahui bagian mana dari pesan yang berisi variabel.
BAGUS
var filePath = @"C:tmpmy-file.txt" ;
try
{
var file = File . Open ( filePath ) ;
}
catch ( Exception ex )
{
// GOOD: Add [ ] to the variable
Log . Error ( $ "Could not open file [ { filePath } ]." , ex ) ;
}BURUK
var filePath = @"C:tmpmy-file.txt" ;
try
{
var file = File . Open ( filePath ) ;
}
catch ( Exception ex )
{
Log . Error ( $ "Could not open file { filePath } ." , ex ) ;
}TUJUAN: Sehingga pengecualian dapat disaring dalam kasus tertentu (misalnya dalam antarmuka pengguna, karena seluruh jejak tumpukan tidak berguna bagi pengguna).
BAGUS
try
{
var file = File . Open ( @"C:tmpmy-file.txt" ) ;
}
catch ( Exception ex )
{
// Use appropriate signature of your logger to include the exception as separate parameter
Log . Error ( "Could not open file." , ex ) ;
}BURUK
try
{
var file = File . Open ( @"C:tmpmy-file.txt" ) ;
}
catch ( Exception ex )
{
// Strictly AVOID this. The exception is added directly to the log message, which makes it impossible to filter the exception
Log . Error ( $ "Could not open file: { ex } " ) ;
}