Software Development Refactoring Wisdom I gained through Reviewing My Own Code
1. Click Ctrl + RR to refactor in Visual Studio 2019, a timer server.
2. Find where the squiggly lines are in code and follow the recommendation
Things I learned While Refactoring My Code
1. Using blocks in C# can be simplified by simply enclosing the directive or part of code needed to be instantiated in a Using block
e.g using var httpClient = new HttpClient(handler);
2. I learned that, when using an Out Type in a Method, you actually do not need to create a variable to hold that Out value from the Method, Simply write your function as:
Uri.TryCreate("urlInHere",UriKind.Absolute,out Uri someVariableYouDon'tNeedToCreateUpTop);
- Then you could just reference the someVariableYouDon'tNeedToCreateUpTop in your code.
- When programming, try to use Uri("urlInHere"); other than creating or marking a URL as a String. When you create too many String variables, you halt the application performance as strings get created on the HEAP Memory Stack that eventually will trigger the Garbage (GC) Collection. When the Garbage Collector is triggered, mainly the performance suffers at that point. If possible make sure whatever you do, you do not make GC triggered.
- This can be avoided by creating your Variables inside a function as functions get cleaned up or disposed of after the operation has ended.
- Another way to avoid GC's is to minimize Object Instatietions, keep in mind only Objects you need, try not to create too many Global Objects or Variables.
- Try to minimize Static Attributes in a class as those might linger around during the Application Life Cycle and could be allocated in Memory.
[NB] Pay Attention to the Warnings you see in Visual Studio, if not this will bite you later during Application Optimization.
3. CA1062: In Internally Visible Method Validate Parameter is non-null
- When you see this warning, it basically tells you to make sure you validate if the Parameter is not null before you proceed using it. Remember to use minimal Try{}Catch(){} block in your code, too many Exceptions show how bad your code is. If possible check for null or handler-specific Exceptions.
- The shortest and cleanest way to check for null values is by marking the variable you think might be Null with a question-mark like so:
_request = contextRequest?.HttpContext; //this way the _request variable can only be populated if the contextRequest is not null.
- Minimize General Exception Handling such Try{}Catch(Exception ex){} this will load the all entire Exception Library Stack and then try to scan for Specific Error or Exception. If possible try to be specific in telling the Compiler what Exception you think will be thrown, if it is Input Output (IO) related then specify that in Catch() function.
4. CA1305: Severity Code Description Project File Line Suppression State
Warning CA1305 The behavior of 'Convert.ToInt32(string)' could vary based on the current user's locale settings. Replace this call in 'MethodName' with a call to 'Convert.ToInt32(string, IFormatProvider)'
- When you see this Warning in your Project's code, see the solution below:
Solution: Create a read only property of private IFormatProvider _provider; then assign the value in the Constructor of your Repository Class like so:
namespace MyProject.Services.RepositoryService
{
public class MyNiceClassRepository : IMyNiceInterface
{
private readonly IFormatProvider _provider;
public MyNiceClassRepository( IFormatProvider provider)
{
_provider = provider;
}
public void MyFunction(){
//This is where you can use _provider
int myInt = Convert.ToInt32(ProductID,_provider);
}
}
}
5. If possible pass in IEnumerable list in your function Parameter if you need to instead of passing in a concrete List. This is because Lists inherits from IEnumerable Interface so, the caller doesn't have to convert their argumentes/parameter to List to fit what is defined as a function's parameter.
//Helpful and will save you some time
//This is type Agnostic, you can pass in List, Querable, and other Generic Implementation of IEnumerable
public async Task<IEnumerable<T>> GetProductResouces(IEnumerable someParameter)
{
//Operatioan on someParameter e.g. Sort,Search etc.
return someParameter;
}
//Problematic and might bite you in future
//This requires the caller to only pass in the Type of List
public async Task<List<Products>> GetProductResouces(List someParameter)
{
//Operatioan on someParameter e.g. Sort,Search etc.
return someParameter;
}
References
- https://docs.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions
- https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1062
-https://docs.microsoft.com/en-us/dotnet/standard/exceptions/how-to-use-the-try-catch-block-to-catch-exceptions
- https://docs.microsoft.com/en-us/dotnet/standard/exceptions/