Style Guide
Table of Contents
Overview
This document provides an overview of standard naming conventions in C#, aspx, and SQL so we can be more consistent with our code across applications.
C Sharp
Source: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions
Naming Conventions
It is a good rule of thumb to use names that reflect the function of the variable or method being defined. That way, the person who ends up maintaining the code spends less time trying to figure out what your code does.
Variables
When declaring a variable, use camel case:
string myVariable = "fooBar";
Functions/Methods
When defining a function, use Pascal case:
protected void MyFunction (string myVariable) {}
Also, note the space between the function name and parameters. Details like this are small, but go a long way in making code readable.
Layout Conventions
General Layout Guidelines
- 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).
- 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. }
- Using curly braces as shown above is a best practice, even if they are not strictly needed. That way if you have to add more statements or nest additional conditions inside the original statement it is less confusing.
Comments
- 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.
- Ideally, more complex helper methods should have a block comment at the beginning describing the general purpose of the method and how it does what it does.
aspx
Naming Conventions
The formula for naming controls is, lowercase control-specific prefix + underscore + Pascal-cased descriptive name for control. Here are some examples for the most common controls used in PBC's pages:
Check Boxes
cb_MyCheckBox
Check Box Lists
cbl_MyCheckBoxList
Data Sources
sql_MyDataSource
Drop Down Lists
ddl_MyDropDownList
Grid Views
gv_MyGridView
Labels
lbl_MyLabel
Link Buttons
lbt_MyLinkButton
List Boxes
lb_MyListBox
Multi Views
mv_MyMultiView
Radio Buttons
rb_MyRadioButton
Radio Button Lists
rbl_MyRadioButtonList
Text Boxes
tb_MyTextBox
User Controls
uc_MyUserControl
Validators
Validators come in two flavors: Required, and Custom.
rfv_MyRequiredFieldValidator
cv_MyCustomValisdator
Views
mvv_MyView
Layout Conventions
Don't underestimate the value of indentation and spacing. For instance, this:
<asp:Label ID="lbl_MyFirstLabel" Text="Good Layout Example" runat="server">
<table>
<td>
<tr>
<sam3:CodeListDropDown ID="cldd_MyFirstCodeListDropDown" runat="server"/>
</tr>
</td>
</table>
is much easier to read and understand than this:
<asp:Label ID="lbl_MySecondLabel" Text="Bad Layout Example" runat="server">
<table><td><tr>
<sam3:CodeListDropDown ID="cldd_MySecondCodeListDropDown" runat="server"/> </tr></td>
</table>
Generally, the rule of thumb is to use a new line for each new control, and indent with one tab for each new nested div, view, multiview, table row, and table column. It is also important to avoid superflous white space between lines. To take another example, this:
<asp:Panel ID="pn_MyFirstPanel" runat="server">
<asp:MultiView ID="mv_MyFirstMultiView" runat="server">
<asp:View ID="mvv_MyFirstView" runat="server">
<asp:Label ID="lbl_MyFirstLabel" runat="server" />
</asp:Label>
</asp:View>
</asp:MultiView>
</asp:Panel>
is much easier to read and understand than this:
<asp:Panel ID="pn_MyFirstPanel" runat="server">
<asp:MultiView ID="mv_MyFirstMultiView" runat="server">
<asp:View ID="mvv_MyFirstView" runat="server">
<asp:Label ID="lbl_MyFirstLabel" runat="server" />
</asp:Label>
</asp:View>
</asp:MultiView>
</asp:Panel>
SQL
Naming Conventions
Variables
When declaring a variable, use Pascal case:
declare @MyVariable varchar(20) = "Hello World!";
Tables and Stored Procedures
When naming a new table or stored procedure, use the following convention:
smart.<projectname>_<Sproc_OrTableDescription>
For instance,
smart.p11_Load_IntakeForm
Layout Conventions
General Layout Guidelines
Write only one statement/declaration per line.
In general, try to put
SELECT
FROM
andWHERE
statements on separate lines from one another. For instance, this:-- Ex. 1 WITH Products as ( SELECT DISTINCT Split.a.value('.', 'VARCHAR(100)') AS Product FROM (SELECT CAST ('<M>' + REPLACE(ProductList, ',', '</M><M>') + '</M>' AS XML) AS Product FROM smart.P11_IntakeForm_DropSample where UniqueDropSampleNo = @UniqueDropSampleNo) AS A CROSS APPLY Product.nodes ('/M') AS Split(a) )
is much more dificult to read than this:
-- Ex. 2 WITH Products as ( SELECT DISTINCT Split.a.value('.', 'VARCHAR(100)') AS Product FROM ( SELECT CAST ('<M>' + REPLACE(ProductList, ',', '</M><M>') + '</M>' AS XML) AS Product FROM smart.P11_IntakeForm_DropSample WHERE UniqueDropSampleNo = @UniqueDropSampleNo ) AS A CROSS APPLY Product.nodes ('/M') AS Split(a) )
- The same should be done for other types of statements. For instance, this:
is much more dificult to read than this:-- Ex. 3 UPDATE smart.p11_intakeform_DropSample SET [AccountEffectiveDate] = LTRIM(RTRIM([AccountEffectiveDate])),[AccountName] = LTRIM(RTRIM([AccountName])) [AccountNo] = LTRIM(RTRIM([AccountNo])),[BONTID] = LTRIM(RTRIM([BONTID])),[BusinessType] = LTRIM(RTRIM([BusinessType])),[BuyerGroup] = LTRIM(RTRIM([BuyerGroup]))
Unlike in example 3, in in example 4 it is very easy to see the exact variables in the-- Ex. 4 UPDATE smart.p11_intakeform_DropSample SET [AccountEffectiveDate] = LTRIM(RTRIM([AccountEffectiveDate])), [AccountName] = LTRIM(RTRIM([AccountName])), [AccountNo] = LTRIM(RTRIM([AccountNo])), [BONTID] = LTRIM(RTRIM([BONTID])), [BusinessType] = LTRIM(RTRIM([BusinessType])), [BuyerGroup] = LTRIM(RTRIM([BuyerGroup]))
SET
statement, and you're less likely to miss one.
Use appropriate indentation
- Sub-queries should be indented for clarity (see examples 1 and 2 above).
- It is better if join clauses are indented too. For instance, this:
Is more dificult to read than this:-- Ex. 5 insert into smart.p11_IntakeForm_Count select a.UniqueInstanceNo, e.LookupNo, a.[Medical], e.Option1, 0 from JoinedInstance a inner join smart.p11_Sample b on a.SampleNo = b.SampleNo inner join smart.p11_Dynamic_IntakeField c on b.DynamicIntakeFormNo = b.DynamicIntakeFormNo and IntakeFieldNo = 27 inner join smart.p11_Dynamic_IntakeOption d on c.DynamicIntakeFieldNo = d.DynamicIntakeFieldNo inner join smart.p11_CodeList e on e.LookupCategory = 'Count' and e.LookupNo = d.IntakeOptionNo and e.LookupTitle = 'Medical' where b.Deleted = 0 and c.Deleted = 0 and d.Deleted = 0 and a.[Medical] > 0
But, this:-- Ex. 6 insert into smart.p11_IntakeForm_Count select a.UniqueInstanceNo, e.LookupNo, a.[Medical], e.Option1, 0 from JoinedInstance a smart.p11_Sample b on a.SampleNo = b.SampleNo inner join smart.p11_Dynamic_IntakeField c on b.DynamicIntakeFormNo = b.DynamicIntakeFormNo and IntakeFieldNo = 27 inner join smart.p11_Dynamic_IntakeOption d on c.DynamicIntakeFieldNo = d.DynamicIntakeFieldNo inner join smart.p11_CodeList e on e.LookupCategory = 'Count' and e.LookupNo = d.IntakeOptionNo and e.LookupTitle = 'Medical' where b.Deleted = 0 and c.Deleted = 0 and d.Deleted = 0 and a.[Medical] > 0
Is even easier to read, as the-- Ex. 7 insert into smart.p11_IntakeForm_Count select a.UniqueInstanceNo, e.LookupNo, a.[Medical], e.Option1, 0 from JoinedInstance a inner join smart.p11_Sample b on a.SampleNo = b.SampleNo inner join smart.p11_Dynamic_IntakeField c on b.DynamicIntakeFormNo = b.DynamicIntakeFormNo and IntakeFieldNo = 27 inner join smart.p11_Dynamic_IntakeOption d on c.DynamicIntakeFieldNo = d.DynamicIntakeFieldNo inner join smart.p11_CodeList e on e.LookupCategory = 'Count' and e.LookupNo = d.IntakeOptionNo and e.LookupTitle = 'Medical' where b.Deleted = 0 and c.Deleted = 0 and d.Deleted = 0 and a.[Medical] > 0
join
andand
clauses are at the start of each line so you immediately know which opperation is being carried out. Moreover, if you need to change an operation you don't have to scroll all the way to the right and search for it. You know right where it is as everything is aligned.
- Try not to use both upper case clauses and lower case ones in the same stored procedure. It's good to be consistent. For instace, do this:
instead of this:-- Ex. 8 select a.UniqueInstanceNo, a.SampleNo, a.SampleName, a.PlatformNo, a.BusinessAreaNo, a.AuditTypeNo from smart.p10_qry_InstanceHeader a left join smart.p10_ReportTable_Demographics b on a.UniqueInstanceNo = b.UniqueInstanceNo where a.ReportMonth between @StartMonth and @EndMonth + 1
Alternately, all uppercase clauses would have also been fine.--Ex. 9 SELECT a.UniqueInstanceNo, a.SampleNo, a.SampleName, a.PlatformNo, a.BusinessAreaNo, a.AuditTypeNo From smart.p10_qry_InstanceHeader a left join smart.p10_ReportTable_Demographics b On a.UniqueInstanceNo = b.UniqueInstanceNo where a.ReportMonth between @StartMonth and @EndMonth + 1
Git
Commit Messages
Do not underestimate the value of a descriptive commit message. It helps you and others understand what your change entailed and why it was necessary. For instance, this is a very unhelpful commit message:
$git commit -m "Added some new features."
The person who comes behind you has no easy way of understanding your changes. A more helpful commit message would be:
$git commit -m "[CP email notifications] Email notifications working
> Added a new condition to handle sending email notifications for
claims not audited in 250K. Changed the body of these emails to
reflect client needs."
or, equivilently:
$git commit -m "[CP email notifications] Email notifications working' -m 'Added
a new condition to handle sending email notifications for claims not audited in
250K. Changed the body of these emails to reflect client needs."
So the general format of a good commit message is:
[Name of the page or control you changed] Brief description of change
Elaboration on details of the change and why it was nescessary.
Branch Naming
It is also very helpful to other members of the team when branches are named appropriately. Again, the name should reflect what is being added or changed on the branch.
Names of branches should be prefixed with bugfix/
feature/
hotfix/
or release/
. This is an example of poorly named branch:
my-new-features
And this is an example of a well-named branch:
feature/250K-CP-needs-email-notifications-on-claim-deletion