Thursday 9 March 2017

7 Habits of highly effective C# Programmer(3 Series) - Part 3

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



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. 

7 Habits of highly effective C# Programmer(3 Series) - Part 1

7 Habits of highly effective C# Programmer(3 Series) - Part 2

 

 

Tuesday 7 March 2017

7 Habits of highly effective C# Programmer(3 Series) - Part 2

  
3. Use `Yield` Keyword in Statement
This is one of the keyword that should be widely used when you know the input’s length is un-deterministic. It can be used to create composable API’s using generics. Yield follows nothing but a deferred execution model.  
Let us look into the example before any explanation, with an usecase. Until you  understand the use case where it can be used, it is tough to catch up the logic and usage behind the Yield keyword.
private static IEnumerable<int> TestFibbonacciWithoutYield(int limit)
       {
           int f1 = 0, f2 = 1, f3 = 0;
           Console.WriteLine("Fibonacci Series:");
    //IList collections is needed to hold values
           IList<int> collections = new List<int>();
           
           for (int i = 0; i < limit; i++)
           {
               f3 = f1 + f2;
               Console.WriteLine("Fibonacci Series sequence:" + i);
               collections.Add(f1);
               f1 = f2;
               f2 = f3;
           }
           return collections;
       }


In the above function we have iterated through limit to print the fibbononacci series, when the function is called with
           IEnumerable<int> collections = Program.TestFibbonacciWithoutYield(10);


           foreach (int fibonnacciSeries in Program.TestFibbonacciWithoutYield(10))
           {
               Console.WriteLine(fibonnacciSeries + " ,");
           }


The output will be as below.


The collection is filled with values, then the collection is printed, what if the limit that is set as  TestFibbonacciWithoutYield(1 million) (yes with 6 zeroes !!!) is million so a list will be created with one million integer values are traversed and printed.
So the solution is to use Yield keyword to remove the unnecessary list that needs to hold the values   which in turn  holds the application memory.


Below code does use the yield keyword
private static IEnumerable<int> TestFibbonacciWithYield(int limit)
       {
           int f1 = 0, f2 = 1, f3 = 0;
           Console.WriteLine("Fibonacci Series:");
           //---You dont need the IList collections;
           for (int i = 0; i < limit; i++)
           {
               f3 = f1 + f2;
               Console.WriteLine("Fibonacci Series sequence(i): "  + i);
               f1 = f2;
               f2 = f3;
               yield return f1;


           }
       }
Note in the above example even though the return type of TestFibbonacciWithYield() is IEnumerable<int> , there are no collections that are created in the method.
When we call the method as below.
static void Main(string[] args)
       {
           IEnumerable<int> collections = Program.TestFibbonacciWithYield(10);


           foreach (int fibonnacciSeries in collections)
           {
               Console.WriteLine(fibonnacciSeries + " ,");
           }
           Console.ReadKey();
       }


The output denotes the fibonnaci series is generated only when the foreach has accessed the element instead of running all once.
So what happens here exactly in Yield Keyword?
TestFibbonacciWithoutYield()  method, allocates the entire storage for the sequence of elements, and TestFibbonacciWithYield(), ask for the next element on the input sequence only when needed, and they produce the next value on the output sequence only when the calling code asks for it.
Yield plays an interesting trick, it returns a value and retains information about its current location and current state of its internal iteration. Both the input and output are iterators. This is called as continuation method. Continuation methods keep track of their state and resume execution at their current location when code enters them again.
So what is advantage other than reduced need to create a new collection in the TestFibbonacciWithoutYield()  method ?
Yield provides deferred lazy loading meaning, you can access elements whenever you need it. Imagine a scenario where the input limit for the Fibonacci series is million (Yes 1 with six zeroes), then we might need to hold a list that has 1 million records in the memory. You might not want that, because all you need is to print them.
IEnumerable<int> collections = Program.TestFibbonacciWithYield(100000).Skip(50000);
In above command will do a deferred loading to skip first 50,000 records and print the remaining values. Imagine the memory you have said. You can use Yield in places where the input is un-deterministic and you need to make sure the application handles the deferred loading. I wish Yield is available in javascript(ECMA 5.0 or earlier, I heard it is in ECMA 6).


4. Understanding Closure
Due to all the invasion of functional programming concept into the .Net 3.0 and forward, we are getting many benefits in oops language like C# , functional way of thinking. In functional programming world the functions are passed from one functions to another as we pass objects from one object to another in OOPS World. Closure is very important concept that needs to be understood, it is fairly simple and straightforward. I like to keep the sample as simple as possible. I have dumbed down the example, so you can understand the concepts of closure first and then we will see why you should bother understanding them in the first place.
Before starting our understanding, we need to understand a term called “First- Class Function”.
First class function is nothing but a variable that can hold functions.
i.e... function that can be passed as a variable and stored in a  data-structure. As of now, if you know what is function pointer then you can consider it as First class function. In C# we can achieve it by lambda functions or anonymous methods. Explaining more about it and talking about functional programming is out of scope of our blog. So we will dive into an example straightaway.


private static int  StraightForwardFunction(int noToPrint)
       {
            
           return IncrementingFunction(noToPrint);
       }
       private static int IncrementingFunction(int value)
       {
           value = value + 1;
           return value;
       }
In above StraightForwardFunction() function we are passing the noToPrint to Incrementing function and the value is incremented and passed back.
static void Main(string[] args)
    {
      Console.WriteLine(ClosureProgram.StraightForwardFunction(5));
      Console.WriteLine(ClosureProgram.StraightForwardFunction(6));                          
    }
When we run the StraightForwardFunction, the output will be as below with incremented value 6 and 7
Let us see how delegate function works in this regard.
public static Func<int, int> TestClosure()
       {
           var mainScope = 0;
           return delegate (int local)
           {
               mainScope = mainScope + 1;
               return local + mainScope;
           };
            
       }
In the above function TestClosure(), when called twice with value as below
var closureCall = TestClosure();            
Console.WriteLine($"Closure Incremented Value:  {closureCall(5)}");
            Console.WriteLine($"Closure Incremented Value:  {closureCall(6)}");
We should expect the value to be incremented to 6 and 8 respectively. But the answer is not 6 and 7. See below.
When the function is called twice, the value is persisted with the delegate that compose of incrementing the value and the value is incremented with last main scope variable.
Strange right? All the years what we have read about the scopes enclosed in curly braces seems to be wrong with the above delegate. Let us see what happens when a delegate used to do some work when the IL is created.




The closure function is enclosed with class and so the variables are persisted when we use the delegate, which is the reason, why the variable incremented to 8 instead of 7.
But in case of StraightForwardFunction, the IL created was only as function as below
But why should I care what IL and C# compiler does ?, how does knowing this make me effective c# programmer. The answer is, IT DOES.
As developers we’ve grown accustomed to looking at the lifetime of local variables in a very simple way. Variables come into scope when we declare them, and they are garbage collected when the corresponding block closes.
Closures and captured variables change those rules, When you use a variable that is bound by closure, it’s reference to the variable does not go out of scope until the last delegate referencing that captured variable goes out of scope. Under some circumstances it may even last longer.
What happens when we hold an expensive resources that has implemented IDisposable and needs to be explicitly cleaned up? So you need to understand how objects created are returned from methods and you must ensure that the closure clean them up for you.

7 Habits of highly effective C# Programmer(3 Series) - Part 1

7 Habits of highly effective C# Programmer(3 Series) - Part 3



Build Bot using LUIS