Rules to Better Code - 80 Rules
What makes code "cleaner"? What makes the difference between readable code and very readable code?
It can be very painful when needing to modify a piece of code in an application that you never spec'd out or wrote. But it doesn't have to be this way. By following some of these better programming tips your code can be easily read and easily modified by any developer at any time.
Refactoring is all about making code easier to understand and cheaper to modify without changing its behavior.
As a rule of thumb, no method should be greater than 50 lines of code. Long-winded methods are the bane of any developer and should be avoided at all costs. Instead, a method of 50 lines or more should be broken down into smaller functions.
You should generally be looking for ways to simplify your code (e.g. removing heavily-nested case statements). As a minimum, look for the most complicated method you have and check whether it needs simplifying.
In Visual Studio, there is built-in support for Cyclomatic Complexity analysis.
- Go to Analyze | Calculate Code Metrics | For Solution
- Look at the function with the largest Cyclomatic Complexity number and consider refactoring to make it simpler.
Tip: Aim for "green" against each function's Maintainability Index.
Too often, developers are writing a line of code, and they forget that little bit of syntax they need to do what they want. In that case, they usually end up googling it to find the documentation and then copy and paste it into their code. That process is a pain because it wastes valuable dev time. They might also ask another dev for help.
Not to worry, AI pair programming is here to save the day!
Video: 6 ways GitHub Copilot helps you write better code faster (7 min) Video: Say hello to GitHub Copilot Enterprise! (17 min)New tools like GitHub Copilot provide devs with potentially complete solutions as they type. It might sound like it's too good to be true, but in reality you can do so much with these tools.
"It’s hard to believe that GitHub Copilot is actually an AI and not a Mechanical Turk. The quality of the code is at the very least comparable to my own (and in fairness that's me bragging), and it's staggering to see how accurate it is in determining your needs, even in the most obscure scenarios."
- Matt GoldmanWhat can it do?
There is a lot to love with AI pair programming ❤️, here is just a taste of what it can do:
Help with writing code
- Populate a form
- Do complex maths
- Create DTOs
- Hydrate data
- Query APIs
- Do unit tests
GitHub Copilot - Help with reading and understanding code
- Generate Pull Request summaries
- Explore and learn about a codebase
- Understand PBIs and how to implement them
Some tools that offer this are GitHub Copilot or Codeium (not to be confused with Codium).
Why is it awesome?
AI pair programming has so much to offer, here are the key benefits:
- Efficiency - Less time doing gruntwork like repetitive tasks and making boilerplate
-
Learnability - Quick suggestions in heaps of languages, such as:
- C#
- JavaScript
- SQL, and many more
Code duplication is a big "code smell" that harms maintainability. You should keep an eye out for repeated code and make sure you refactor it into a single place.
For example, have a look at these two Action methods in an MVC 4 controller.
// // GET: /Person/ [Authorize] public ActionResult Index() { // get company this user can view Company company = null; var currentUser = Session["CurrentUser"] as User; if (currentUser != null) { company = currentUser.Company; } // show people in that company if (company != null) { var people = db.People.Where(p => p.Company == company); return View(people); } else { return View(new List()); } } // // GET: /Person/Details/5 [Authorize] public ActionResult Details(int id = 0) { // get company this user can view Company company = null; var currentUser = Session["CurrentUser"] as User; if (currentUser != null) { company = currentUser.Company; } // get matching person Person person = db.People.Find(id); if (person == null || person.Company == company) { return HttpNotFound(); } return View(person); }
Figure: Bad Example - The highlighted code is repeated and represents a potential maintenance issue.
We can refactor this code to make sure the repeated lines are only in one place.
private Company GetCurrentUserCompany() { // get company this user can view Company company = null; var currentUser = Session["CurrentUser"] as User; if (currentUser != null) { company = currentUser.Company; } return company; } // // GET: /Person/ [Authorize] public ActionResult Index() { // get company this user can view Company company = GetCurrentUserCompany(); // show people in that company if (company != null) { var people = db.People.Where(p => p.Company == company); return View(people); } else { return View(new List()); } } // GET: /Person/Details/5 [Authorize] public ActionResult Details(int id = 0) { // get company this user can view Company company = GetCurrentUserCompany(); // get matching person Person person = db.People.Find(id); if (person == null || person.Company == company) { return HttpNotFound(); } return View(person); }
Figure: Good Example - The repeated code has been refactored into its own method.
Tip: The Refactor menu in Visual Studio 11 can do this refactoring for you.
One of the major issues people had back in the day with ASP (before ASP.NET) was the prevalence of "Spaghetti Code". This mixed Reponse.Write() with actual code.
Ideally, you should keep design and code separate - otherwise, it will be difficult to maintain your application. Try to move all data access and business logic code into separate modules.
Bob Martin explains this best:
When moving through the different stages of testing i.e. from internal testing, through to UAT, you should suffix the application name with the appropriate stage:
Stage Testing Description Naming Convention Alpha Developer testing with project team Northwindv2-3alpha.exe Beta Internal “Test Please" testing with non-project working colleagues Northwindv2-3beta.exe Production e.g. When moving onto production, this naming convention is dropped Northwind_v2-3.exe It is not a good idea to have spaces in a folder or file name as they don't translate to URLs very well and can even cause technical problems.
Instead of using spaces, we recommend:
- kebab-case - using dashes between words
Other not recommended options include:
- CamelCase - using the first letter of each word in uppercase and the rest of the word in lowercase
- snake_case - using underscores between words
For further information, read Do you know how to name documents?
This rule should apply to any file or folder that is on the web. This includes Azure DevOps Team Project names and SharePoint Pages.
- extremeemailsversion1.2.doc
- Extreme Emails version 1.2.doc
Figure: Bad examples - File names have spaces or dots
- extreme-emails-v1-2.doc
- Extreme-Emails-v1-2.doc
Figure: Good examples - File names have dashes instead of spaces
- sharepoint.ssw.com.au/Training/UTSNET/Pages/UTS%20NET%20Short%20Course.aspx
- fileserver/Shared%20Documents/Ignite%20Brisbane%20Talk.docx
Figure: Bad examples - File names have been published to the web with spaces so the URLs look ugly and are hard to read
- sharepoint.ssw.com.au/Training/UTS-NET/Pages/UTS-NET-Short-Course.aspx
- fileserver/Shared-Documents/Ignite-Brisbane-Talk.docx"
Figure: Good examples - File names have no spaces so are much easier to read
Try to avoid problems in if-statements without curly brackets and just one statement which is written one line below the if-statement. Use just one line for such if-statements. If you want to add more statements later on and you could forget to add the curly brackets which may cause problems later on.
if (ProductName == null) ProductName = string.Empty; if (ProductVersion == null) ProductVersion = string.Empty; if (StackTrace == null) StackTrace = string.Empty;
Figure: Bad Example
if (ProductName == null) { ProductName = string.Empty; } if (ProductVersion == null) { ProductVersion = string.Empty; } if (StackTrace == null) { StackTrace = string.Empty; }
Figure: Good Example
Try to avoid Double-Negative Conditionals in if-statements. Double negative conditionals are difficult to read because developers have to evaluate which is the positive state of two negatives. So always try to make a single positive when you write if-statement.
if (!IsValid) { // handle error } else { // handle success }
Figure: Bad example
if (IsValid) { // handle success } else { // handle error }
Figure: Good example
if (!IsValid) { // handle error }
Figure: Another good example
Use pattern matching for boolean evaluations to make your code even more readable!
if (IsValid is false) { // handle error }
Figure: Even better
Do you know String should be @-quoted instead of using escape character for "\"?The @ symbol specifies that escape characters and line breaks should be ignored when the string is created.
As per: Strings
string p2 = "\\My Documents\\My Files\\";
Figure: Bad example - Using "\"
string p2 = @"\My Documents\My Files\";
Figure: Good example - Using @
Raw String Literals
In C#11 and later, we also have the option to use raw string literals. These are great for embedding blocks of code from another language into C# (e.g. SQL, HTML, XML, etc.). They are also useful for embedding strings that contain a lot of escape characters (e.g. regular expressions).
Another advantage of Raw String Literals is that the redundant whitespace is trimmed from the start and end of each line, so you can indent the string to match the surrounding code without affecting the string itself.
var bad = "<html>" + "<body>" + "<p class=\"para\">Hello, World!</p>" + "</body>" + "</html>";
Figure: Bad example - Single quotes
var good = """ <html> <body> <p class="para">Hello, World!</p> </body> </html> """;
Figure: Good example - Using raw string literals
For more information on Raw String literals see learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/raw-string
You should always add the application name to the connection string so that SQL Server will know which application is connecting, and which database is used by that application. This will also allow SQL Profiler to trace individual applications which helps you monitor performance or resolve conflicts.
<add key="Connection" value="Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Biotrack01;Data Source=sheep;"/>
Bad example - The connection string without Application Name
<add key="Connection" value="Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Biotrack01;Data Source=sheep; Application Name=Biotracker"/> <!-- Good Code - Application Name is added in the connection string. -->
Good example - The connection string with Application Name
There are 2 type of connection strings. The first contains only address type information without authorization secrets. These can use all of the simpler methods of storing configuration as none of this data is secret.
Option 1 - Using Azure Managed Identities (Recommended)
When deploying an Azure hosted application we can use Azure Managed Identities to avoid having to include a password or key inside our connection string. This means we really just need to keep the address or url to the service in our application configuration. Because our application has a Managed Identity, this can be treated in the same way as a user's Azure AD identity and specific roles can be assigned to grant the application access to required services.
This is the preferred method wherever possible, because it eliminates the need for any secrets to be stored. The other advantage is that for many services the level of access control available using Managed Identities is much more granular making it much easier to follow the Principle of Least Privilege.
Option 2 - Connection Strings with passwords or keys
If you have to use some sort of secret or key to login to the service being referenced, then some thought needs to be given to how those secrets can be secured.Take a look at Do you store your secrets securely to learn how to keep your secrets secure.
Example - Integrating Azure Key Vault into your ASP.NET Core application
In .NET 5 we can use Azure Key Vault to securely store our connection strings away from prying eyes.
Azure Key Vault is great for keeping your secrets secret because you can control access to the vault via Access Policies. The access policies allows you to add Users and Applications with customized permissions. Make sure you enable the System assigned identity for your App Service, this is required for adding it to Key Vault via Access Policies.
You can integrate Key Vault directly into your ASP.NET Core application configuration. This allows you to access Key Vault secrets via
IConfiguration
.public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder .UseStartup<Startup>() .ConfigureAppConfiguration((context, config) => { // To run the "Production" app locally, modify your launchSettings.json file // -> set ASPNETCORE_ENVIRONMENT value as "Production" if (context.HostingEnvironment.IsProduction()) { IConfigurationRoot builtConfig = config.Build(); // ATTENTION: // // If running the app from your local dev machine (not in Azure AppService), // -> use the AzureCliCredential provider. // -> This means you have to log in locally via `az login` before running the app on your local machine. // // If running the app from Azure AppService // -> use the DefaultAzureCredential provider // TokenCredential cred = context.HostingEnvironment.IsAzureAppService() ? new DefaultAzureCredential(false) : new AzureCliCredential(); var keyvaultUri = new Uri($"https://{builtConfig["KeyVaultName"]}.vault.azure.net/"); var secretClient = new SecretClient(keyvaultUri, cred); config.AddAzureKeyVault(secretClient, new KeyVaultSecretManager()); } }); });
Good example - For a complete example, refer to this sample application
Tip: You can detect if your application is running on your local machine or on an Azure AppService by looking for the
WEBSITE_SITE_NAME
environment variable. If null or empty, then you are NOT running on an Azure AppService.public static class IWebHostEnvironmentExtensions { public static bool IsAzureAppService(this IWebHostEnvironment env) { var websiteName = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"); return string.IsNullOrEmpty(websiteName) is not true; } }
Setting up your Key Vault correctly
In order to access the secrets in Key Vault, you (as User) or an Application must have been granted permission via a Key Vault Access Policy.
Applications require at least the LIST and GET permissions, otherwise the Key Vault integration will fail to retrieve secrets.
Azure Key Vault and App Services can easily trust each other by making use of System assigned Managed Identities. Azure takes care of all the complicated logic behind the scenes for these two services to communicate with each other - reducing the complexity for application developers.
So, make sure that your Azure App Service has the System assigned identity enabled.
Once enabled, you can create a Key Vault Access policy to give your App Service permission to retrieve secrets from the Key Vault.
Adding secrets into Key Vault is easy.
- Create a new secret by clicking on the Generate/Import button
- Provide the name
- Provide the secret value
- Click Create
Note: The ApplicationSecrets section is indicated by "ApplicationSecrets--" instead of "ApplicationSecrets:".
As a result of storing secrets in Key Vault, your Azure App Service configuration (app settings) will be nice and clean. You should not see any fields that contain passwords or keys. Only basic configuration values.
Video: Watch SSW's William Liebenberg explain Connection Strings and Key Vault in more detail (8 min)
History of Connection Strings
In .NET 1.1 we used to store our connection string in a configuration file like this:
<configuration> <appSettings> <add key="ConnectionString" value ="integrated security=true; data source=(local);initial catalog=Northwind"/> </appSettings> </configuration>
...and access this connection string in code like this:
SqlConnection sqlConn = new SqlConnection(System.Configuration.ConfigurationSettings. AppSettings["ConnectionString"]);
Historical example - Old ASP.NET 1.1 way, untyped and prone to error
In .NET 2.0 we used strongly typed settings classes:
Step 1: Setup your settings in your common project. E.g. Northwind.Common
Step 2: Open up the generated App.config under your common project. E.g. Northwind.Common/App.config
Step 3:
Copy the content into your entry applications app.config. E.g. Northwind.WindowsUI/App.configThe new setting has been updated to app.config automatically in .NET 2.0<configuration> <connectionStrings> <add name="Common.Properties.Settings.NorthwindConnectionString" connectionString="Data Source=(local);Initial Catalog=Northwind; Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration>
...then you can access the connection string like this in C#:
SqlConnection sqlConn = new SqlConnection(Common.Properties.Settings.Default.NorthwindConnectionString);
Historical example - Access our connection string by strongly typed generated settings class...this is no longer the best way to do it
Most systems will have variables that need to be stored securely; OpenId shared secret keys, connection strings, and API tokens to name a few.
These secrets must not be stored in source control. It is insecure and means they are sitting out in the open, wherever code has been downloaded, for anyone to see.
There are many options for managing secrets in a secure way:
Bad Practices
Store production passwords in source control
Pros:
- Minimal change to existing process
- Simple and easy to understand
Cons:
- Passwords are readable by anyone who has either source code or access to source control
- Difficult to manage production and non-production config settings
- Developers can read and access the production password
Figure: Bad practice - Overall rating: 1/10
Store production passwords in source control protected with the ASP.NET IIS Registration Tool
Pros:
- Minimal change to existing process – no need for DPAPI or a dedicated Release Management (RM) tool
- Simple and easy to understand
Cons:
- Need to manually give the app pool identity ability to read the default RSA key container
- Difficult to manage production and non-production config settings
- Developers can easily decrypt and access the production password
- Manual transmission of the password from the key store to the encrypted config file
Figure: Bad practice - Overall rating: 2/10
Use Windows Identity instead of username / password
Pros:
- Minimal change to existing process – no need for DPAPI or a dedicated RM tool
- Simple and easy to understand
Cons:
- Difficult to manage production and non-production config settings
- Not generally applicable to all secured resources
- Can hit firewall snags with Kerberos and AD ports
- Vulnerable to DOS attacks related to password lockout policies
- Has key-person reliance on network admin
Figure: Bad practice - Overall rating: 4/10
Use External Configuration Files
Pros:
- Simple to understand and implement
Cons:
- Makes setting up projects the first time very hard
- Easy to accidentally check the external config file into source control
- Still need DPAPI to protect the external config file
- No clear way to manage the DevOps process for external config files
Figure: Bad practice - Overall rating: 1/10
Good Practices
Use Octopus/ VSTS RM secret management, with passwords sourced from KeePass
Pros:
- Scalable and secure
- General industry best practice - great for organizations of most sizes below large corporate
Cons:
- Password reset process is still manual
- DPAPI still needed
Figure: Good practice - Overall rating: 8/10
Use Enterprise Secret Management Tool – Keeper, 1Password, LastPass, Hashicorp Vault, etc
Pros:
- Enterprise grade – supports cryptographically strong passwords, auditing of secret access and dynamic secrets
- Supports hierarchy of secrets
- API interface for interfacing with other tools
- Password transmission can be done without a human in the chain
Cons:
- More complex to install and administer
- DPAPI still needed for config files at rest
Figure: Good practice - Overall rating: 8/10
Use .NET User Secrets
Pros:
- Simple secret management for development environments
- Keeps secrets out of version control
Cons:
- Not suitable for production environments
Figure: Good practice - Overall rating 8/10
Use Azure Key Vault
See the SSW Rewards mobile app repository for how SSW is using this in a production application: https://github.com/SSWConsulting/SSW.Rewards
Pros:
- Enterprise grade
- Uses industry standard best encryption
- Dynamically cycles secrets
- Access granted based on Azure AD permissions - no need to 'securely' share passwords with colleagues
- Can be used to inject secrets in your CI/CD pipelines for non-cloud solutions
- Can be used by on-premise applications (more configuration - see Use Application ID and X.509 certificate for non-Azure-hosted apps)
Cons:
- Tightly integrated into Azure so if you are running on another provider or on premises, this may be a concern. Authentication into Key Vault now needs to be secured.
Figure: Good practice - Overall rating 9/10
Avoid using secrets with Azure Managed Identities
The easiest way to manage secrets is not to have them in the first place. Azure Managed Identities allows you to assign an Azure AD identity to your application and then allow it to use its identity to log in to other services. This avoids the need for any secrets to be stored.
Pros:
- Best solution for cloud (Azure) solutions
- Enterprise grade
- Access granted based on Azure AD permissions - no need to 'securely' share passwords with colleagues
- Roles can be granted to your application your CI/CD pipelines at the time your services are deployed
Cons:
- Only works where Azure AD RBAC is available. NB. There are still some Azure services that don't yet support this. Most do though.
Figure: Good practice - Overall rating 10/10
Resources
The following resources show some concrete examples on how to apply the principles described:
- github.com/brydeno/bicepsofsteel
- Microsoft Learn | Best practices for using Azure Key Vault
- Microsoft Learn | Azure Key Vault security
- Microsoft Learn | Safe storage of app secrets in development in ASP.NET Core
- Microsoft Learn | Connection strings and configuration files
- Microsoft Learn | Use managed identities to access App Configuration
- Stop storing your secrets with Azure Managed Identities | Bryden Oliver
You may be asking what's a secret for a development environment? A developer secret is any value that would be considered sensitive.
Most systems will have variables that need to be stored securely; OpenId shared secret keys, connection strings, and API tokens to name a few. These secrets must not be stored in source control. It's not secure and means they are sitting out in the open, wherever code has been downloaded, for anyone to see.
There are different ways to store your secrets securely. When you use .NET User Secrets, you can store your secrets in a JSON file on your local machine. This is great for development, but how do you share those secrets securely with other developers in your organization?
Video: Do you share secrets securely | Jeoffrey Fischer (7min)An encryption key or SQL connection string to a developer's local machine/container is a good example of something that will not always be sensitive for in a development environment, whereas a GitHub PAT token or Azure Storage SAS token would be considered sensitive as it allows access to company-owned resources outside of the local development machine.
❌ Bad practices
❌ Do not store secrets in appsettings.Development.json
The
appsettings.Development.json
file is meant for storing development settings. It is not meant for storing secrets. This is a bad practice because it means that the secrets are stored in source control, which is not secure.Figure: Bad practice - Overall rating: 1/10
❌ Do not share secrets via email/Microsoft Teams
Sending secrets over Microsoft Teams is a terrible idea, the messages can land up in logs, but they are also stored in the chat history. Developers can delete the messages once copied out, although this extra admin adds friction to the process and is often forgotten.
Note: Sending the secrets in email, is less secure and adds even more admin for trying to remove some of the trace of the secret and is probably the least secure way of transferring secrets.
Figure: Bad practice - Overall rating: 3/10
✅ Good practices
✅ Remind developers where the secrets are for a project
For development purposes once you are using .NET User Secrets you will still need to share them with other developers on the project.
As a way of giving a heads up to other developers on the project, you can add a step in your
_docs\Instructions-Compile.md
file (see rule on making awesome documentation) to inform developers to get a copy of the user secrets. You can also add a placeholder to theappsettings.Development.json
file to remind developers to add the secrets.Figure: Good practice - Remind developers where the secrets are for this project
✅ Use 1ty.me to share secrets securely
Using a site like 1ty.me allows you to share secrets securely with other developers on the project.
Pros:
- Simple to share secrets
- Free
Cons:
- Requires a developer to have a copy of the
secrets.json
file already - Developers need to remember to add placeholders for developer specific secrets before sharing
- Access Control - Although the link is single use, there's no absolute guarantee that the person opening the link is authorized to do so
Figure: Good practice - Overall rating 8/10
✅ Use Azure Key Vault
Azure Key Vault is a great way to store secrets securely. It is great for production environments, although for development purposes it means you would have to be online at all times.
Pros:
- Enterprise grade
- Uses industry standard best encryption
- Dynamically cycles secrets
- Access Control - Access granted based on Azure AD permissions - no need to 'securely' share passwords with colleagues
Cons:
- Not able to configure developer specific secrets
- No offline access
- Tightly integrated into Azure so if you are running on another provider or on premises, this may be a concern
- Authentication into Key Vault requires Azure service authentication, which isn't supported in every IDE
Figure: Good practice - Overall rating 8/10
✅ (Recommended) Use Enterprise Secret Management Tool – Keeper, 1Password, LastPass, Hashicorp Vault, etc
Enterprise Secret Management tools have are great for storing secrets for various systems across the whole organization. This includes developer secrets
Pros:
- Developers don't need to call other developers to get secrets
- Placeholders can be placed in the stored secrets
- Access Control - Only developers who are authorized to access the secrets can do so
Cons:
- More complex to install and administer
- Paid Service
Figure: Good practice - Overall rating 10/10
Tip: You can store the full
secrets.json
file contents in the enterprise secrets management tool.Most enterprise secrets management tool have the ability to retrieve the secrets via an API, with this you could also store the
UserSecretId
in a field and create a script that updates the secrets easily into the correctsecrets.json
file on your development machine.Clear text email addresses in web pages are very dangerous because it gives spam sender a chance to pick up your email address, which produces a lot of spam/traffic to your mail server, this will cost you money and time to fix.
Never put clear text email addresses on web pages.
<!--SSW Code Auditor - Ignore next line(HTML)--> <a href="mailto:test@ssw.com.au">Contact Us</a>
Bad - Using a plain email address that it will be crawled and made use of easily
<a href="javascript:sendEmail('74657374407373772e636f6d2e6175')" onmouseover="javascript:displayStatus('74657374407373772e636f6d2e6175');return true;" onmouseout="javascript:clearStatus(); return true;">Contact Us</a>
Good - Using an encoded email address
Tip: If you use Wordpress, use the Email Encoder Bundle plugin to help you encode email addresses easily.
We have a program called SSW CodeAuditor to check for this rule.
One of our goals is to make the job of the developer as easy as possible. If you have to write a lot of code for something that you think you should not have to do, you should make a suggestion and add it to the relevant page.
If you have to add a suggestion, make sure that you put the link to that suggestion into the comments of your code.
/// <summary> /// base class for command implementations /// This is a work around as standard MVVM commands /// are not provided by default. /// </summary> public class Command : ICommand { // code }
Figure: Bad example - The link to the suggestion should be in the comments
/// <summary> /// base class for command implementations /// This is a work around as standard MVVM commands /// are not provided by default. /// </summary> /// /// <remarks> /// Issue Logged here: https://github.com/SSWConsulting/SSW.Rules/issues/3 ///</remarks> public class Command : ICommand { // code }
Figure: Good example - When you link to a suggestion everyone can find it and vote it up
Use casts only if:a. You know 100% that you get that type backb. You want to perform a user-defined conversion
private void AMControlMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { var auc = (AMUserControl)sender; var aucSessionId = auc.myUserControl.Tag; // snip snip snip }
Bad example
private void AMControlMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { var auc = sender as AMUserControl; if (auc != null) { var aucSessionId = auc.myUserControl.Tag; // snip snip snip } }
Good example
More info here: http://blog.gfader.com/2010/08/avoid-type-casts-use-operator-and-check.html
Empty Visual C# .NET methods consume program resources unnecessarily. Put a comment in code block if its stub for future application.Don’t add empty C# methods to your code. If you are adding one as a placeholder for future development, add a comment with a TODO.
Also, to avoid unnecessary resource consumption, you should keep the entire method commented until it has been implemented.
If the class implements an inherited interface method, ensure the method throws NotImplementedException.
public class Example { public double salary() { } }
Figure: Bad Example - Method is empty
public class Sample { public double salary() { return 2500.00; } }
Figure: Good Example - Method implements some code
public interface IDemo { void DoSomethingUseful(); void SomethingThatCanBeIgnored(); } public class Demo : IDemo { public void DoSomethingUseful() { // no audit issues Console.WriteLine("Useful"); } // audit issues public void SomethingThatCanBeIgnored() { } }
Figure: Bad Example - No Comment within empty code block
public interface IDemo { void DoSomethingUseful(); void SomethingThatCanBeIgnored(); } public class Demo : IDemo { public void DoSomethingUseful() {