5. Use nameof
This feature is available in C# 6.0 and forward. You can use it in MVC links (do people still use MVC.Net??). But main places we can use is reporting the namespace in log that causes error and also in places where we use the reflection to get the DLL assembly from a string value.
When we get the assembly using the hardcoded string, when the DLL name or namespace is changed it will cause runtime exception but when we use nameof() we can catch the changes as compiler error. I will not get into detail but it is very nice feature to use for runtime loading dll using string values. For more details look here
6. Use IQueryable extension
Before understanding the IQueryable extension, you need to understand the IQueryable vs IEnumerable.
IEnumerable
Exposes an enumerator, which supports a simple iteration over a non-generic collection
IEnumerable <Customer> customerList = _context.Customers.Where(c => c.Title.Contains("E"));c.Name.StartsWith("E"));
When above query is run against a database with datacontext all the items are fetched from the database and then the name that starts with “E” gets filtered in the local application.
And the other data that does not starts with E gets thrown away. So you’ll transfer much more data through the wire and you’ll throw away whatever isn’t necessary. Enumerable sequence converts LINQ to objects implementation and are executed using delegates.
IQueryable
Provides functionality to evaluate queries against a specific data source wherein the type of the data is not specified.
IQueryable<Customer> customerQuery = _context.Customers.Where(c => c.Title.Contains("E"));
When above query is run against a database with the data-context the filter is applied in the database server and then the result is send to the local application. So you’ll transfer only the relevant data that is needed by the local application. IQueryable queries converts LINQ to T-SQL in case of MS-SQL and then the query is run against the database.
Because of the differences in how IEnumerable and IQueryable process query expressions, you’ll find that sometimes queries that work in one environment do not work in the other. So you need to make sure the dataprovider you are using supports the LINQ functions in IQueryable. For e.g... Any() is supported in MS-SQL but not supported in Azure document db.
So how can I choose IEnumerable and IQueryable based on the data provider without overloading two different methods for IEnumerable and IQueryable?
IQueryable<Customer> customerList = dataContext.Employees.AsQueryable().Where(c => c.Name.StartsWith("E"));
AsQueryable() gives you the maximum benefit. Sequences that already implement IQueryable will use that implementation. Sequences that support only IEnumerable will still work. If your data provider supports startswith then then the data is fetched with filter in the database or if it is not supported then the IEnumerable way of processing kicks in.
Now we will look into the IQueryable extensions
In the above example I have actively and consciously avoided the null check and other robust code to keep it simple. You need to look into the expression building alone and other parameters are same for almost all the method. Above extension will provide the below query for any database irrespective of the data provider. E.g... Azure document database too.
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title]
FROM [Customers] AS [Extent1]
WHERE [Extent1].[Title] LIKE N'E%'
So understand IQueryable extension and start building query expression on your own to generate business specific custom queries that executes in the database and provides you proper output to handle the data effectively. I looked into library in github, but not used, it looks good to me. https://github.com/ninjanye/searchextensions
7.Consider Weak Reference for large Objects
You can use Weak reference for large objects, they are almost garbage. It will be garbage collected whenever the GC is run.
Let us consider an example in which you need to read a 1 GB of a file and you will access only for one single operation, but you might need it or you might not need it based on some use case. If the object is garbage collected then we can created it again. So we are off loading the very hard optimization problem to runtime.
WeakReference w = new WeakReference(largeObject);
largeObject = w.Target as MyLargeClass;
if (largeObject == null)
{
largeObject = new MyLargeClass();
}
This advice comes with a considerable caution and warning: Weak reference may make your code run faster but it has large impact on the garbage collector. Make sure you benchmark your application with weak reference and also without weak reference, so you carefully measure the difference.
You can download the above samples from https://github.com/karthikeyanVK/EffecticeCSharpBlog
You can download the above samples from https://github.com/karthikeyanVK/EffecticeCSharpBlog
Above all 7 features should be used wherever possible and you need to make your code better in every programming language you write code. So getting better every day is part of our daily goal.
Every day you should be better than yesterday, every time you write your code and rewrite your code again it should be better than it was. Do not compare yourself with anyone as better programmer, compare yourself with yesterday where you better today.
Comparing you with another programmer will only lead to stress, you can follow them and get inspired, but don’t compare yourself.
Please post your 7 effective C# features you use which helps you become a effective programmer as comments and am very happy to learn from you.