#### Table des matières
* [Formatting Rules](#formattingRules)
+ [Programming](#programming)
+ [Indentation](#indentation)
+ [Layout](#layout)
+ [Comments](#comments)
+ [Case](#case)
+ [Names of Identifiers](#namesIdentifiers)
+ [Names of Solutions](#namesSolutions)
+ [Names of Projects](#namesProjects)
+ [Names of Namespaces](#namesNamespaces)
+ [Names of Assemblies](#namesAssemblies)
+ [Names of Dlls](#namesDlls)
+ [Names of Classes](#namesClasses)
+ [Names of Structs](#namesStructs)
+ [Names of Enums](#namesEnums)
+ [Names of Methods](#namesMethods)
+ [Names of Properties](#namesProperties)
+ [Names of Events](#namesEvents)
+ [Names of Fields](#namesFields)
+ [Names of Parameters](#namesParameters)
+ [Names of Resources](#namesResources)
* [Style Rules](#styleRules)
+ [General Coding Conventions](#codingConventions)
+ [General Naming Conventions](#namingConventions)
+ [General Comment Conventions](#commentConventions)
* [Links](#links)
[Back to top](#top)
# C# Guideline
Les guidelines présentées dans ce document suivent les recommandations faites par Microsoft.
Les guidelines Microsoft sont disponibles sur MSDN: [Framework Design Guidelines](https://msdn.microsoft.com/en-us/library/ms229042.aspx).
## Formatting Rules
### Programming
Programmez en **anglais**.
### Indentation
Utilisez une indentation de 4 espaces.
N'utilisez pas de tabulations.
Indentez votre code.
### Layout
Utilisez la syntaxe **expanded**.
\*Exception, la syntaxe **collapsed** est autorisée lorsque qu'il n'y a qu'une seule instruction par bloc.
```
namespace Company.Product
{
public class ClassName
{
public int Property { get; set; }
public void DoMethod (int parameter)
{
if(true)
{
// Insert code here.
}
}
}
}
```
Ecrivez une seule déclaration par ligne.
Ecrivez une seule instruction par ligne.
```
public class ClassName
{
private int index, count;
public void DoMethod ()
{
index = count = 0;
}
}
```
Ajoutez au moins une ligne vide entre les définitions de méthodes et les définitions de propriétés.
Utilisez des parenthèses pour les clauses conditionnelles.
```
if ((val1 > val2) && (val1 > val3))
{
// ...
}
```
### Comments
Ajoutez un espace entre le délimiteur de commentaire et le texte du commentaire.
```
// The following declaration creates a query. It does not run
// the query.
```
Documentez le code à l'aide [des commentaires de documentation XML](https://msdn.microsoft.com/library/b2s063f7%28v%3Dvs.140%29.aspx).
```
public class TestClass
{
/// DoWork is a method in the TestClass class.
/// Here's how you could make a second paragraph in a description. for information about output statements.
///
///
/// Used to indicate status.
/// Used to specify context.
public static void DoWork(int integerNumber, float decimalNumber)
{
}
static void Main()
{
}
}
```
### Case
Il y a 2 syntaxe de casses utilisées:
* **Pascal Case**:
applique une majuscule au premier caractère de chaque mot (y compris les acronymes).
```
PropertyDescriptor
```
```
IOStream
```
* **Camel Case**:
applique une majuscule au premier caractère de chaque mot **excepté** pour le premier mot.
```
value
```
```
aField
```
Évitez que les noms des identifiants diffèrent uniquement par leur casse.
#### Evitez ces erreurs fréquentes !
| Pascal case | Camel case | Erreur fréquente |
| --- | --- | --- |
| ``` Id ``` | ``` id ``` | ``` ID ``` |
| ``` Ok ``` | ``` ok ``` | ``` OK ``` |
| ``` Database ``` | ``` database ``` | ``` DataBase ``` |
| ``` Hashtable ``` | ``` hashtable ``` | ``` HashTable ``` |
| ``` Callback ``` | ``` callback ``` | ``` CallBack ``` |
| ``` Placeholder ``` | ``` placeholder ``` | ``` PlaceHolder ``` |
| ``` Metadata ``` | ``` metadata ``` | ``` MetaData ``` |
| ``` UserName ``` | ``` userName ``` | ``` Username ``` |
| ``` FileName ``` | ``` fileName ``` | ``` Filename ``` |
| ``` Endpoint ``` | ``` endpoint ``` | ``` EndPoint ``` |
| ``` Email ``` | ``` email ``` | ``` EMail ``` |
### Names of Identifiers
| Identifiant | Case | Exemple |
| --- | --- | --- |
| Namespace | Pascal | ``` namespace System.Security { // Insert code here. } ``` |
| Class | Pascal | ``` public class StreamReader { // Insert code here. } ``` |
| Interface | Pascal | ``` public interface IEnumerable { // Insert code here. } ``` |
| Method | Pascal | ``` public class Object { public virtual string ToString(); } ``` |
| Property | Pascal | ``` public class String { public int Length { get; } } ``` |
| Event | Pascal | ``` public class Process { public event EventHandler Exited; } ``` |
| Field | Pascal | ``` public class MessageQueue { public static readonly TimeSpan InfiniteTimeout; public struct UInt32 { public const Min = 0; } } ``` |
| Enum type | Pascal | ``` public enum FillMode { // Insert code here. } ``` |
| Enum value | Pascal | ``` public enum FillMode { Append, Insert, Prepend } ``` |
| Parameter | Camel | ``` public class Convert { public static int ToInt32(string value); } ``` |
| Local variable | Camel | ``` public static class Math { public static int Multiply(int multiplicand, int multiplicator) { int product = multiplicand * multiplicator; return product; } } ``` |
### Names of Solutions
Nommez vos solutions en Pascal case conformément à la règle suivante:
```
.
```
```
// Recommended
Actiris.Jobs
Actiris.MonActiris
```
### Names of Projects
Nommez vos projets en Pascal case conformément à la règle suivante:
```
.(|)[.]
```
```
// Recommended
// Framework examples
Actiris.Jobs.Model
Actiris.Jobs.Data
Actiris.Jobs.Service
// Product examples
Actiris.MonActiris.Model
Actiris.MonActiris.Data
Actiris.MonActiris.Service
Actiris.MonActiris.Web.AspNetCore
Actiris.MonActiris.Web.AspNet
Actiris.MonActiris.Windows.Universal
Actiris.MonActiris.Xamarin.IPhone
Actiris.MonActiris.Xamarin.Android
```
### Names of Namespaces
Nommez vos espaces de noms conformément à la règle suivante:
```
.(|)[.][.]
```
```
// Recommended
// Framework examples
Actiris.Security
Actiris.IO.Pdf
Actiris.IO.Excel
Actiris.Web.TagHelpers
// Product examples
Actiris.MonActiris.Web.Controllers
Actiris.MonActiris.Web.ViewModels
```
N'utilisez pas le nom d'un namespace comme nom d'un type au sein du namespace.
```
// Not Recommended
namespace Actiris.MonActiris.Debug
{
public class Debug
{
}
}
```
### Names of Assemblies
Choisissez un nom d'assembly suggérant un ensemble de fonctionnalités, tel que `System.Data`.
Nommez vos assemblies pour qu'ils correspondent au namespace.
```
// Recommended
Actiris.Controls.Calendar
Actiris.Controls.DataGrid
```
### Names of DLLs
Nommez vos DLLs conformément à la règle suivante:
```
..dll
```
```
Actiris.Controls.dll
```
### Names of Classes
Utilisez un nom ou un groupe nominal pour nommer vos classes.
```
// Recommended
public class Employee {...}
public class Job {...}
public class Document {...}
```
Ajoutez à la fin du nom d'une classe dérivée le nom de la classe de base si cela est pertinent.
```
// Recommended
public class ArgumentOutOfRangeException {...}
public class SerializableAttribute {...}
```
### Names of Interfaces
Préfixez les interfaces avec la lettre "I". Utilisez un adjectif, nom ou un group nominale pour nommer vos interfaces.
```
// Recommended
public interface IComponent {...}
public interface ICustomAttributeProvider {...}
public interface IPersistable {...}
```
### Names of Structs
Utilisez un nom ou un groupe nominal pour nommer vos structures.
```
// Recommended
public struct Coordinates {...}
```
### Names of Enums
Utilisez un nom singulier pour nommer vos enums.
```
// Recommended
public enum LogLevel {...}
public enum ServerStatus {...}
public enum ModelState {...}
public enum JobType {...}
```
N'ajoutez pas un suffixe Enum, Flag(s) à vos enums.
```
// Not Recommended
public enum TypeEnum {...}
public enum StatusFlags {...}
```
### Names of Methods
Utilisez un verbe ou une locution verbale pour nommer vos méthodes.
```
// Recommended
public class String
{
public int CompareTo(...) { ... }
public string[] Split(...) { ... }
public string Trim() { ... }
}
```
### Names of Properties
Utilisez un nom, un groupe nominale ou un adjectif pour nommer vos propriétés.
```
// Recommended
public class Galaxy
{
public string Name { get; set; }
public int MegaLightYears { get; set; }
}
```
Utilisez le pluriel pour nommer une propriété de type collection.
N'ajoutez pas de suffixe "List" ou "Collection" à une propriété de type collection.
```
// Not Recommended
public class Universe
{
public List GalaxyList { get; set; }
}
```
```
// Recommended
public class Universe
{
public List Galaxies { get; set; }
}
```
Utilisez un nom affirmatif pour nommer vos propriétés de type Boolean.
Ajoutez le suffixe "Is", "Has", "Can" à une propriété de type Boolean si cela est pertinent.
```
// Recommended
public class Planet
{
public bool HasWater { get; set; }
public bool IsClassified { get; set; }
public bool CanSupportLife { get; set; }
}
```
### Names of Events
Utilisez un verbe ou une locution verbale pour nommer vos événements.
```
Clicked
```
```
Painting
```
```
DroppedDown
```
N'ajoutez pas le préfixe ou le suffixe "Before", "After" pour indiquer la chronologie d'un événement.
Privilégiez l'utilisation du temps présent ou passé.
Exemple: Pour un événement de fermeture d'une fenêtre, si l'événement est déclenché avant que la fenetre soit fermée nommez votre événement `Closing`.
Mais si votre événement est déclenché après que la fenêtre soit fermée, nommez votre événement `Closed`.
```
// Not Recommended
public class CustomClass
{
public event EventHandler BeforeClose;
public event EventHandler AfterClose;
}
```
```
// Recommended
public class CustomClass
{
public event EventHandler Closing;
public event EventHandler Closed;
}
```
Nommez vos events handlers (delegates utilisées comme type d'événements) avec le suffixe "EventHandler".
Utilisez 2 paramètres nommé sender et e dans un event handler.
```
// Recommended
public delegate void ClickedEventHandler(object sender, ClickedEventArgs e);
```
Utilisez le suffixe "EventArgs" pour les classes de type event argument.
```
// Recommended
public class CustomEventArgs : EventArgs {...}
```
### Names of Fields
Utilisez un nom, un groupe nominal ou un adjectif pour nommer vos champs.
Utilisez le Pascal case pour nommer un champ "public" ou "protected".
### Names of Parameters
Utilisez le Camel case pour nommer vos paramètres.
Utilisez des noms de paramètres explicites et claires.
```
// Not Recommended
public class Utilities
{
public int ConvertHoursToSeconds(int h, int m, int s) {...}
}
```
```
// Recommended
public class Utilities
{
public int ConvertHoursToSeconds(int hours, int minutes, int seconds) {...}
}
```
### Names of Resources
Utilisez le Pascal case pour nommer les clées de ressources.
Utilisez des noms de ressources explicites et claires.
N'utilisez pas de caractères spéciaux, utilisez uniquement des caractères alphanumériques et des underscores.
Utilisez le point "." comme séparateur entre objet et propriété.
```
EditJob
```
```
SaveJobEditing
```
```
CancelJobEditing
```
```
ActirisLogo.Source
```
```
ActirisLogo.AlternateText
```
## Style Rules
### General Coding Conventions
Programmez en **anglais**.
#### File Conventions
Évitez d'ajouter plus d'une classe par fichier.
Le nom du fichier doit correspondre avec la nom de la classe qu'il contient.
#### Code Conventions
Évitez d'avoir plus de 500 lignes de code par fichier.
Évitez d'avoir plus de 30 lignes de code par méthode.
Exception: cette limite ne s'applique pas aux fichiers auto-générés.
Évitez d'utilisez plus de 5 arguments par méthodes. Dans le cas contraire, utilisez une classe ou une structure pour passer de multiples arguments.
#### Exception Conventions
Ne traitez pas les erreurs en capturant des exceptions non-spécifiques tel que `System.Exception` ou `System.SystemException`.
```
// Not Recommended
public class ExceptionHandlingExample
{
public void DoWork()
{
// Do some work that might throw exceptions.
}
public void MethodWithBadHandler()
{
try
{
DoWork();
}
catch (Exception e)
{
// Handle the exception and continue executing.
}
}
}
```
Ne soulevez pas d'exceptions de type `System.Exception` ou `System.SystemException`.
```
// Not Recommended
public void DoWork()
{
if(true)
{
throw new Exception();
}
}
```
Utilisez un `throw` vide lorsque vous repropagez l'exception afin de préserver la pile d'appel.
```
// Not Recommended
public void DoWork()
{
try
{
// Try to access a resource.
}
catch (System.UnauthorizedAccessException e)
{
LogError(e);
throw e;
}
}
```
```
// Recommended
public void DoWork()
{
try
{
// Try to access a resource.
}
catch (System.UnauthorizedAccessException e)
{
LogError(e);
throw;
}
}
```
#### Using Directive Conventions
Privilégiez l'import des namespaces à l'utilisation des fully qualified object names.
En d'autres mots, n'utilisez les fully qualified object names que si il y a un conflit de noms d'objets.
```
// Not Recommended
using System;
namespace Demo
{
public class Sample
{
private System.Collections.Generic.List names = new System.Collections.Generic.List();
}
}
```
```
// Recommended
using System;
using System.Collections.Generic;
namespace Demo
{
public class Sample
{
private List names = new List();
}
}
```
#### Encapsulation Conventions
Ne délcarez pas des champs de classe `public` ou `protected`.
Un champ de classe ne devrait jamais être `public` ou `protected`.
Dans le cas où vous voulez accéder au champ, privilégiez l'utilisation des propriétés.
#### Type Conventions
Privilégiez les types prédéfinis du langage C# et non les alias du namespace System.
```
// Not Recommended
Object data;
String name;
Int32 id;
```
```
// Recommended
object data;
string name;
int id;
```
#### Implicitly Typed Local Variables
Utilisez uniquement le typage implicite pour les variables locales lorsque le type de la variable est évident ou lorsque le type n'est pas important.
```
// Not Recommended
// When the type of a variable is not clear from the context, use an explicit type.
int total = ExampleClass.ResultSoFar();
```
```
// Recommended
// When the type of a variable is clear from the context, use var in the declaration.
var hello = "Hello World!";
var amount = 42;
var number = Convert.ToInt32(Console.ReadLine());
```
#### Index Conventions
Utilisez toujours un indexe basé sur zéro pour les arrays.
Utilisez toujours un indexe basé sur zéro pour les collections indexées.
### General Naming Conventions
Choisisez un nom d'identifiant compréhensible, clair et conforme à l'anglais.
```
// Not Recommended
public int AlignmentHorizontal { get; set; }
```
```
// Recommended
public int HorizontalAlignment { get; set; }
```
Privilégiez la lisibilité à la brieveté.
N'utilisez pas d'abbréviation. Ne tronquez pas une partie du nom d'un identifiant.
Exception: Le nom d'une variable utilisée pour itérer dans une boucle peut être abrégé.
Évitez les acronymes excepté s'ils sont communément admis.
```
// Not Recommended
public bool ScrollableX { get; set; }
public int NatNum { get; set; }
public int T { get; set; }
```
```
// Recommended
public bool CanScrollHorizontally { get; set; }
public int NationalNumber { get; set; }
public int Temp { get; set; }
```
```
for (int i = 0; i < 10; i++)
{
// Insert code here.
}
```
N'utilisez pas d'underscore, trait d'unions ou de caractère spéciaux.
```
// Not Recommended
public class Student
{
private string student_name;
private int student-age;
private string nomÉcole;
}
```
N'utilisez pas la notation hongroise c'est-à-dire ne préfixez pas les variables par leur type.
```
// Not Recommended
public class Student
{
private string sName;
private int iAge;
private List lCourse;
static int s_iStudentsNumber;
}
```
Evitez d'utiliser des mots réservés propre au language de programmation.
```
// Not Recommended
public class Student
{
private string @class;
}
```
### General Comment Conventions
Commentez le code lorsque cela est nécessaire.
Evitez d'ajouter des commentaires pour expliquer ce qui est évident. Le code devrait être suffisament clair pour être compris de par lui même.
Toutefois, utilisez les commentaires pour expliquer le code; lorsque celui-ci est complexe ou lorsque qu'une correction a dû être apportée.
Documentez le code à l'aide [des commentaires de documentation XML](https://msdn.microsoft.com/library/b2s063f7%28v%3Dvs.140%29.aspx).
Utilisez la documentation Xml pour fournir aux utilisateurs les informations dont ils ont besoin de savoir sur le comportement général du code.
N'utilisez pas la documentation Xml pour préciser des détails sur l'implémentation du code.
Dans le cas d'une API, documentez chaque méthode.
## Links
* [Stack Overflow](http://stackoverflow.com/questions/4678178/style-guide-for-c#answer-4695777)
* [Framework Design Guidelines: Naming Guidelines](https://msdn.microsoft.com/en-us/library/ms229002.aspx)
* [Design Guidelines: Naming Guidelines](https://msdn.microsoft.com/en-us/library/xzf533w0.aspx)
* [Programming Guide: C# Coding Conventions](https://msdn.microsoft.com/en-us/library/ff926074.aspx)
* [All-In-One Code Framework Coding Standards](http://1code.codeplex.com/wikipage?title=All-In-One%20Code%20Framework%20Coding%20Standards&referringTitle=Documentation)
* [C# Coding Standards and Naming Conventions](http://www.dofactory.com/reference/csharp-coding-standards)
* [IDesign: C# Coding Standard](http://www.idesign.net/Downloads/GetDownload/1985)