Friday, January 27, 2017

C# 7 Features - out variable initialization

In my previous article, we discussed about the concept of local functions in C# 7.0. In this article, we will see another feature related to the use of out type variables. 
 
Out variables are not new in C# and provide a big advantage of how we can return multiple values from a method. However, in order to pass a out type variable as a method parameter, we have to declare it first and then pass it into the method parameter, with out keyword. Something like the following: 
  1. static void Main(string[] args)  
  2. {  
  3.   
  4.             int userId;  
  5.             string userName;  
  6.             GetDetails(out userId, out userName);  
  7.   
  8.             Console.ReadKey();  
  9. }  
  10. public static void GetDetails(out Int32 UserId, out string Username)  
  11. {  
  12.             UserId = 12;  
  13.             Username = "Test User";  
  14. }  
However, in C# 7.0, we can declare the variable at the time of passing it as a method parameter, when method is being called. This means the following code will work fine in C# 7.0. 
  1. static void Main(string[] args)  
  2. {  
  3.             GetDetails(out int userId, out string userName);  
  4.             Console.ReadKey();  
  5. }  
Also, now we can have the out variable being declared as of var type, when passed as method parameter. So following code is valid and works fine in C# 7.0, which did not worked in earlier versions of C#. 
  1. static void Main(string[] args)  
  2.         {  
  3.             GetDetails(out var userId, out var userName);  
  4.             Console.ReadKey();  
  5.         }  
Hope you enjoyed reading it. Happy coding...!!!

Wednesday, January 25, 2017

Dynamic methods in C# using CodeDom

In my previous article, we discussed how we can create a dynamic class using CodeDom namespace. Now we will discuss how we can add methods to these classes. For this we will be use the same code as in our previous discussion.
For adding method to the class, we will use CodeMemberMethod class, which provides different properties, to define methods. For our sample we will create a dynamic method which will take two input parameters, calculate their sum and return the sum. Let's with basic method signatures. So our code will look like the following: 
  1. CodeTypeReference methodReturnType = new CodeTypeReference(typeof(System.Int32)); 
  2. CodeMemberMethod myMethod = new CodeMemberMethod();  
  3.   
  4.  // Generate Method signatures.  
  5.  myMethod.Name = "MySum";  
  6.  myMethod.ReturnType = methodReturnType;  
  7.  myMethod.Attributes = MemberAttributes.Public;  
We use of the CodeTypeReference class to specify the return type of our method. To add parameters for this method, we will use the CodeParameterDeclarationExpression class. So our code will look like the following: 
  1. // Initialize for Method parameters  
  2. CodeParameterDeclarationExpression methodPrm1 = new CodeParameterDeclarationExpression(typeof(Int32), "X");  
  3. CodeParameterDeclarationExpression methodPrm2 = new CodeParameterDeclarationExpression(typeof(Int32), "Y");  
  4. myMethod.Parameters.AddRange(new CodeParameterDeclarationExpression[] { methodPrm1, methodPrm2 });  
Next, to specify the method definition we use the CodeSnippetExpression class. Our method will simply the sum of our input parameters. So we will generate an expression to perform the sum of the numbers and add it to the method. So our code will change to the following: 
  1. // Generate method definition  
  2. CodeSnippetExpression codeSnippet = new CodeSnippetExpression("return X + Y");  
  3.   
  4. // Add method definition to method  
  5. myMethod.Statements.Add(codeSnippet);  
Finally we add the method to our class definition using following code: 
  1. // Add method to the class.  
  2. cls.Members.Add(myMethod);  
So our complete code will look like the following: 
  1.  CodeNamespace nameSpace = new CodeNamespace("sampleNameSpace");  
  2.   
  3.  nameSpace.Imports.Add(new CodeNamespaceImport("System"));  
  4.  nameSpace.Imports.Add(new CodeNamespaceImport("System.Linq"));  
  5.  nameSpace.Imports.Add(new CodeNamespaceImport("System.Text"));  
  6.   
  7.  CodeTypeDeclaration cls = new CodeTypeDeclaration();  
  8.  cls.Name = "SampleClass";  
  9.  cls.IsClass = true;  
  10.  cls.Attributes = MemberAttributes.Public;  
  11.  nameSpace.Types.Add(cls);  
  12.   
  13.  // Initialize for Method Return type  
  14.  CodeTypeReference methodReturnType = new CodeTypeReference(typeof(System.Int32));  
  15.  CodeMemberMethod myMethod = new CodeMemberMethod();  
  16.   
  17.  // Generate Method signatures.  
  18.  myMethod.Name = "MySum";  
  19.  myMethod.ReturnType = methodReturnType;  
  20.  myMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;  
  21.   
  22.  // Initialize for Method parameters  
  23.  CodeParameterDeclarationExpression methodPrm1 = new CodeParameterDeclarationExpression(typeof(Int32), "X");  
  24.  CodeParameterDeclarationExpression methodPrm2 = new CodeParameterDeclarationExpression(typeof(Int32), "Y");  
  25.  myMethod.Parameters.AddRange(new CodeParameterDeclarationExpression[] { methodPrm1, methodPrm2 });  
  26.   
  27.  // Generate method definition  
  28.  CodeSnippetExpression codeSnippet = new  CodeSnippetExpression("return X + Y");  
  29.   
  30. // Add method definition to method  
  31.  myMethod.Statements.Add(codeSnippet);  
  32.   
  33.  // Add method to the class.  
  34.  cls.Members.Add(myMethod);  
  35.   
  36.  CodeCompileUnit compileUnit = new CodeCompileUnit();  
  37.  compileUnit.Namespaces.Add(nameSpace);  
  38.  CSharpCodeProvider csharpcodeprovider = new CSharpCodeProvider();  
  39.   
  40.  CSharpCodeProvider provider = new CSharpCodeProvider();  
  41.   
  42.  using (StreamWriter sw = new StreamWriter(@"C:\TestFile.cs"false))  
  43.  {  
  44.      IndentedTextWriter tw = new IndentedTextWriter(sw, "    ");  
  45.      provider.GenerateCodeFromCompileUnit(compileUnit, tw, new CodeGeneratorOptions());  
  46.      tw.Close();  
  47.  }  
Run the application and see the code getting generated: 
  1. //------------------------------------------------------------------------------  
  2. // <auto-generated>  
  3. //     This code was generated by a tool.  
  4. //     Runtime Version:4.0.30319.42000  
  5. //  
  6. //     Changes to this file may cause incorrect behavior and will be lost if  
  7. //     the code is regenerated.  
  8. // </auto-generated>  
  9. //------------------------------------------------------------------------------  
  10.   
  11. namespace sampleNameSpace {  
  12.     using System;  
  13.     using System.Linq;  
  14.     using System.Text;  
  15.       
  16.       
  17.     public class SampleClass {  
  18.           
  19.         public int MySum(int X, int Y) {  
  20.             return X + Y;  
  21.         }  
  22.     }  
  23. }  
So this was about how we can generate the dynamic class and add methods to it. Hope you enjoyed reading it. Happy coding...!!!

Sunday, January 8, 2017

C# 7 features - Local functions


A preview of C# 7.0 has been introduced with the preview release of Visual Studio 15. This should not be confused with Visual studio 2015, as it is separate.

In order to install visual studio 15, you will have to download the setup from the link here - https://blogs.msdn.microsoft.com/vcblog/2016/10/05/visual-studio-15-preview-5-now-available/ and install the web and desktop development tools.

So we will start with the first feature which is the use of Local functions. Normally we create private sub-functions for code refactoring. However, these functions are exposed to other methods in the class, even though they are not required to use. But in C# 7, we can have functions within the functions. Yes, we can create a function within another function.

For example, following code is valid in C# 7.0:

        static void Main(string[] args)
        {
            var d = GetSalary();
        }
        public static Int32 GetSalary()
        {
            var s = GetSum(10, 6) * 2;

            return s;

            Int32 GetSum(Int32 a, Int32 b)
            {
                return a + b;
            }
        }

Run the code and you will get 32 as output.


Here, we have the GetSum method, which will return the sum of two numbers. The result is then multiplied by 2. Hope you enjoyed reading it. Happy coding...!!!

Saturday, January 7, 2017

SingleOrDefault vs FirstOrDefault

LINQ provides with two extension methods SingleOrDefault and FirstOrDefault. Let's see the difference between the twoAdd a new class clsTest and add two properties Id and Name. Create a List clsTest type, add some data. So we have the following code:  
  1. static void Main(string[] args)  
  2.        {  
  3.            List<clsTest> lstTest = new List<clsTest>();  
  4.   
  5.            lstTest.Add(new clsTest  
  6.            {  
  7.                Id = 1,  
  8.                Name = "A"  
  9.            });  
  10.            lstTest.Add(new clsTest  
  11.            {  
  12.                Id = 2,  
  13.                Name = "B"  
  14.            });  
  15.            lstTest.Add(new clsTest  
  16.            {  
  17.                Id = 3,  
  18.                Name = "C"  
  19.            });  
  20.   
  21.   
  22.            var fod = lstTest.Where(l => l.Name == "D").FirstOrDefault();  
  23.            var sod = lstTest.Where(l => l.Name == "D").SingleOrDefault();  
  24.        }  
Here, we are access an element which does not exist in the list. Run the application and we get null. So both of these methods handle the null condition. Now let's add duplicate records and search the record. So the code changes to: 
  1. static void Main(string[] args)  
  2.         {  
  3.             List<clsTest> lstTest = new List<clsTest>();  
  4.   
  5.             lstTest.Add(new clsTest  
  6.             {  
  7.                 Id = 1,  
  8.                 Name = "A"  
  9.             });  
  10.             lstTest.Add(new clsTest  
  11.             {  
  12.                 Id = 2,  
  13.                 Name = "B"  
  14.             });  
  15.             lstTest.Add(new clsTest  
  16.             {  
  17.                 Id = 3,  
  18.                 Name = "C"  
  19.             });  
  20.             lstTest.Add(new clsTest  
  21.             {  
  22.                 Id = 4,  
  23.                 Name = "C"  
  24.             });  
  25.   
  26.             var fod = lstTest.Where(l => l.Name == "C").FirstOrDefault();  
  27.             var sod = lstTest.Where(l => l.Name == "C").SingleOrDefault();  
  28.         }  
Now run the application. We get the exception Sequence contains more than one element for SingleOrDefault. FirstOrDefault returns the first matching record i.e. the record with Id=3. However, This is because, SingleOrDefault cannot handle the situation if there are multiple elements with the same name. However, FirstOrDefault will return the first matching record from the list. Happy coding...!!!