Top Best Practices to Consider

Applies To: Microsoft Dynamics AX 2012 R3, Microsoft Dynamics AX 2012 R2, Microsoft Dynamics AX 2012 Feature Pack, Microsoft Dynamics AX 2012

The following sections provide guidance to avoid best practice violations. The sections provide guidance in the following areas:

  • Formatting

  • Naming

  • Commenting Code

  • XML Documentation

  • Labels and text

  • Database

  • Exceptions

General Best Practice Guidance

The following list provides general best practices guidance.

  • Favor using positive logic.

  • Use constants instead of numeric literals.

  • Use enumerations in place of constants.

  • Use explicit access modifiers.

  • Do not use method parameters as an l-value.

Cc967435.collapse_all(en-us,AX.60).gifFormatting Guidance

The following table provides formatting best practice guidance.

Best Practice

Example

Place the opening brace at the beginning of the next line.

if (someExpression)

{

doSomething();

}

Align the closing brace with the corresponding opening brace.

if (someExpression)

{

doSomething();

}

Place the opening and closing braces each on their own line.

if (someExpression)

{

doSomething();

}

Do not omit braces. Braces are not optional because they increase code readability and maintainability. They should be included, even for single statement blocks.

if (someExpression)

{

doSomething();

}

Omit braces for switch statements. These braces can be omitted because the case and break statements clearly indicate the beginning and ending.

case 0:

doSomething();

break;

Use a single space in the following cases:

  • On either side of the assignment operator.

Correct: cust.Name = "Jo";

Incorrect: cust.Name="Jo";

  • After the comma between parameters.

Correct:

public void doSomething(int _x, int _y)

Incorrect:

public void doSomething(int _x,int _y)

  • Between arguments.

Correct: myAddress(myStr, 0, 1)

Incorrect: myAddress(myStr,0,1)

  • Before flow control statements.

Correct: while (x == y)

Incorrect: while(x == y)

  • Before and after binary operators.

Correct: if (x == y)

Incorrect: if (x==y)

  • After the semicolon between the parts of a for statement.

Correct: for (i = 0; i < 10; i++)

Incorrect: for (i = 0;i < 10;i++)

Do not use any spaces in the following cases:

  • After the opening or before the closing parenthesis.

Correct: myAddress(myStr, 0, 1)

Incorrect: myAddress( myStr, 0, 1 )

  • Between a member name and opening parenthesis.

Correct: myAddress()

Incorrect: myAddress ()

  • Before or after the brackets.

Correct: x = dataArray[index];

Incorrect: x = dataArray[ index ];

  • Before or after unary operators.

Correct: if (!y)

Incorrect: if (! y)

Use four spaces as the standard indent. The tab key in code editor inserts four spaces. Indent in the following cases:

  • The contents of code blocks.

if (someExpression)

{

doSomething();

}

  • Case blocks even though they do not use braces.

switch (someExpression)

{

case 0:

doSomething();

break;

}

  • A wrapped line one indent from the previous line.

lastAccount = this.doSomething(

cust,

firstAccount,

startDate,

endDate);

Wrap lines that get too long to fit on a single line.

Wrap shorter lines to improve clarity.

Place each wrapped select and while select statement keyword at the beginning of a new line. The content associated with each keyword should be indented by one indent under the corresponding keyword.

select firstonly cust

where someExpression1

&& someExpression2

&& someExpression3;

select count(RecId)

from cust

where someExpression1

&& someExpression2

&& someExpression3;

while select firstonly cust

order by Name, AccountNum

where someExpression1

&& someExpression2

&& someExpression3

{

}

Do not use more or less than four spaces to force special alignment.

Right

lastAccount = this.doSomething(

cust,

firstAccount,

startDate,

endDate);

Wrong (indent is 14 spaces)

last = this.do(

cust,

firstAccount,

startDate,

endDate);

Put each indented parameter or argument on a separate line.

Use switch statements over consecutive if statements.

Do not use parenthesis around the value of the cases of a switch statement.

Do not put the closing parenthesis for a method call on a new line.

Cc967435.collapse_all(en-us,AX.60).gifNaming Guidance

The following table provides naming best practice guidance.

Best Practice

Example

Use Camel case naming for member variables, method names, and local variables.

serverClass;

Use Pascal case naming for Application Object Tree (AOT) elements.

AddressCountyRegion;

Prefix parameter names with an underscore (_).

myJob(Args _args)

Do not use Hungarian notation. Do not encode the type of a variable in its name.

Incorrect: strName

Avoid prefixing local variables.

Incorrect: stringName or intCount

Use meaningful and self-documenting names.

Cc967435.collapse_all(en-us,AX.60).gifCommenting Code Guidance

This section provides best practice guidance for writing code comments. Comments should be used to describe the intent, algorithmic overview, and logical flow. Provide comments so that someone other than the original developer could understand the behavior and purpose of the code. It is a best practice that most code will have comments reflecting the developer intent and approach for the code. Use comments liberally. Include comments that indicate who made the changes, when the changes were made, why the changes were added, and what the changes do. Comments are particularly beneficial when multiple parties are involved in modifying and maintaining code. The following table provides code commenting best practice guidance.

Best Practice

Example

Do not use comments that repeat the code.

Do not use multi-line syntax /* … */ for comments. The single-line syntax // … is preferred even when a comment spans multiple lines.

public int getCount()

{

;

// This comment spans multiple

// lines because it has

// a lot to say. The use of

// multi-line syntax is

// not allowed.

}

Do not place comments at the end of a line unless the comment is very short. In most cases, comments should be placed above the code.

public class ArrayList

{

int count; // -1 indicates uninitialized array

}

Remove TODO comments well in advance of a release.

// TODO: The TODO comments should start with TODO.

For more information, see TODO Comments for X++ Developer Tasks.

Cc967435.collapse_all(en-us,AX.60).gifXML Documentation Guidance

XML documentation should provide information related to usage. It should help a programmer decide if they want to use the method. The following list provides best practice guidance for XML documentation.

  • Add XML documentation with meaningful content.

  • Use XML documentation to provide users and potential users with the information they need.

  • Do not use XML documentation to discuss implementation details or other items not related to use.

  • Do not add XML documentation for the sake of improving code coverage.

  • Be aware of the methods with automatically generated XML documentation; for example, New and construct.

Cc967435.collapse_all(en-us,AX.60).gifLabels and Text Guidance

The following list provides best practice guidance for labels and text.

  • Use labels for text that will appear on the user interface.

  • Put labels in double quotes.

  • Do not concatenate multiple labels together.

  • Use single quotes for text that will not appear in the user interface.

Cc967435.collapse_all(en-us,AX.60).gifDatabase Guidance

The following list provides best practice guidance related to the database.

  • Include a try catch around all transactions that could result in deadlock.

  • Make sure the try for a deadlock is idempotent meaning no matter how many times the try is attempted, it will yield the same result.

  • Consider the clarity when deciding the number of return statements in a method.

  • Use throw instead of ttsAbort.

  • Avoid display methods where possible.

  • Set Optimistic Concurrency Control (OccEnabled) to Yes for most tables.

  • Do not include user interaction inside a database transaction.

  • Keep database transactions as short as possible.

  • Run code on the Application Object Server (AOS) whenever possible.

  • Use where clauses in select statements and in queries that align with indexes.

  • If method calls are used to test conditions, put the method calls after the other conditions. If the other conditions fail, then you will not incur the cost of running the method.

  • Minimize the size of database transactions.

  • Consider specifying a field list in select statements to increase performance.

  • Use firstonly where applicable to increase performance.

  • Use aggregates in the selection criteria instead of having the code do the aggregation. If aggregations are issued in the select statement rather than in code, the processing is done at the database server which is much more efficient.

  • Use table joins instead of nested while loops. Whenever possible use a join in the select statement rather than using a while loop and then an inner while loop on the related table. This reduces the amount of communication between the AOS and the database.

  • Do not include any sort of user interaction in a transaction.

Cc967435.collapse_all(en-us,AX.60).gifExceptions Guidance

The following list provides best practice guidance related to exceptions.

  • Throw an exception to stop the currently executing X++ call stack.

  • Include a localized error message with all thrown exceptions.

  • Use the info, warning, and error functions without a thrown exception in cases where the executing X++ call stack should not be stopped.

  • Use throw with the static helpers on the Error class such as Error::missingParameter and Error::wrongUseOfFunction for errors targeted at developers.

  • Do not throw an exception for an error condition that you expect will need to be caught.

  • Do not throw an exception for invalid assumption cases where a Debug::assert is more appropriate.

See also

X++ Coding Standards

Announcements: New book: "Inside Microsoft Dynamics AX 2012 R3" now available. Get your copy at the MS Press Store.