:::: MENU ::::

Thursday, July 31, 2014

In this article I will write about my top 10 tips in C# programming. Each tip will be supported by the sample C# codes, which will make it easy for the C# newbies to get a hold on. 

Tip 1: Write Unit Test Cases for Non-Public Methods

Have you ever tried writing unit test cases for methods of an assembly which are not public? Most developers don’t because they are not visible to the test project. C# allows you to make the assembly internals visible to other assemblies. Adding the attribute shown below in the AssemblyInfo.cs file does the trick.
//Make the internals visible to the test assembly
[assembly: InternalsVisibleTo("MyTestAssembly")]

Tip 2: Use Tuples

I have seen developers creating a POCO class just for the sake of returning multiple values from a method. Tuples are introduced in .NET Framework 4.0 which can be used effectively as shown below.
       public Tuple<int, string, string> GetEmployee()
        {
            int employeeId = 1001;
            string firstName = "Rudy";
            string lastName = "Koertson";
 
            //Create a tuple and return
            return Tuple.Create(employeeId, firstName, lastName);
        }

Tip 3: No Need for Temporary Collections, Yield Might Help

Normally when we need to fetch the items from a collection we might create a temporary list to hold the retrieved items and return. Following is the C# code using the temporary list.
        public List<int> GetValuesGreaterThan100(List<int> masterCollection)
        {
            List<int> tempResult = new List<int>();
 
            foreach (var value in masterCollection)
            {
                if (value > 100)
                    tempResult.Add(value);
            }
            return tempResult;
        }
 To avoid the usage of this temporary collection you could choose to use the yield. It will yield the result as and when the result set is enumerated. Below is the code using the yield keyword.

        public IEnumerable<int> GetValuesGreaterThan100(List<int> masterCollection)
        {
            foreach (var value in masterCollection)
            {
                if (value > 100)
                    yield return value;
            }
        }
Of course you could also use LINQ.

Tip 4: Telling the World that you are Retiring a Method Soon

In case you own a re-distributable component and you are planning to deprecate a method soon, then you can decorate the method with the obsolete attribute to communicate it to the clients. Here is the sample C# code.
        [Obsolete("This method will be deprecated soon. You could use XYZ alternatively.")]
        public void MyComponentLegacyMethod()
        {
            //Here is the implementation
        }
The client applications will get a warning with the given message upon compilation. Incase if you want to fail the client build if they are using the deprecated method then pass the extra Boolean parameter as True.
        [Obsolete("This method is deprecated. You could use XYZ alternatively.", true)]
        public void MyComponentLegacyMethod()
        {
            //Here is the implementation
        }

Tip 5: Remember Deferred Execution While Writing LINQ Queries

In .NET when you write a LINQ query it actually performs the querying only when the LINQ result is accessed. This phenomenon of LINQ is called deferred execution. One thing you should be aware of is that on every access of the result set the query gets executed again and again.
To avoid the repeated execution convert the LINQ result to List upon execution as shown below.
        public void MyComponentLegacyMethod(List<int> masterCollection)
        {
            //Without the ToList this linq query will be executed twice because of the following usage
            var result = masterCollection.Where(i => i > 100).ToList();
 
            Console.WriteLine(result.Count());
            Console.WriteLine(result.Average());
        }

Tip 6: Converting Business Entities Using Explicit Keyword

Use the explicit keyword to define the conversion of one business entity to another. The conversion method will be invoked when the conversion is requested in code. Here is the sample conversion code.
class Program
    {
        static void Main(string[] args)
        {
            ExternalEntity entity = new ExternalEntity()
            {
                Id = 1001,
                FirstName = "Dave",
                LastName = "Johnson"
            };
            MyEntity convertedEntity = (MyEntity)entity;
        }
    }
 
    class MyEntity
    {
        public int Id { get; set; }
        public string FullName { get; set; }
 
        public static explicit operator MyEntity(ExternalEntity externalEntity)
        {
            return new MyEntity()
            {
                Id = externalEntity.Id,
                FullName = externalEntity.FirstName + " " + externalEntity.LastName
            };
        }
    }
 
    class ExternalEntity
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

Tip 7: Retaining the Exact Stack Trace

In a C# program in the catch block if you throw the exception as given below and the error has occurred in the method ConnectDatabase, the thrown exception stack trace will only show that the error has occurred in the RunDataOperation method. It would have lost the actual error source.
        public void RunDataOperation()
        {
            try
            {
                Intialize();
                ConnectDatabase();
                Execute();
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
To retain the actual stack trace throw as shown below.
        public void RunDataOperation()
        {
            try
            {
                Intialize();
                ConnectDatabase();
                Execute();
            }
            catch (Exception)
            {
                throw;
            }
        }

Tip 8: Flags Attribute – Enum Grouping

Decorating the enum with the Flags attribute in C# will enable the enum as bit fields. This allows us to group the enum values. Here is a sample piece of C# code.
    class Program
    {
        static void Main(string[] args)
        {
            int snakes = 14;
            Console.WriteLine((Reptile)snakes);
        }
    }
 
    [Flags]
    enum Reptile
    {
        BlackMamba = 2,
        CottonMouth = 4,
        Wiper = 8,
        Crocodile = 16,
        Aligator = 32
    }
The output for the above code will be “BlackMamba, CottonMouth, Wiper”. If the flags attribute is removed then the output will be 14 as it is.

Tip 9: Enforcing the Base Type for a Generic Type

Let’s say you created a generic class and you need to enforce that the generic type provided in the class should inherit from a specific interface, then you could do it as shown in the below sample.
    class MyGenricClass where T : IMyInterface
    {
        //Body of the class come in here
    }
You could also do it at the method level.
    class MyGenricClass
    {
        public void MyGenericMethod(T t) where T : IMyInterface
        {
            //Generic implementation goes in here
        }
    }

Tip 10: Exposing Property as IEnumerable Doesn’t Mean It’s Readonly

In a class that you have created, if an IEnumerable property is exposed the callers can still be able to modify them as shown.
    class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            ((List<string>)myClass.ReadOnlyNameCollection).Add("######From Client#####");
 
            myClass.Print();
        }
    }
 
    class MyClass
    {
        List<string> _nameCollection = new List<string>();
        public MyClass()
        {
            _nameCollection.Add("Rob");
            _nameCollection.Add("John");
            _nameCollection.Add("Jummy");
            _nameCollection.Add("Derek");
        }
        public IEnumerable<string> ReadOnlyNameCollection
        {
            get { return _nameCollection.AsEnumerable(); }
        }
 
        public void Print()
        {
            foreach (var item in ReadOnlyNameCollection)
            {
                Console.WriteLine(item);
            }
        }
    }
 
The code does successfully modify the list and adds a new name. One way to avoid this is to add AsReadOnly instead of AsEnumerable.
        public IEnumerable<string> ReadOnlyNameCollection
        {
            get { return _nameCollection.AsReadOnly(); }
        }
I hope this article was informative though you might be aware of few things already. Happy reading!
"ApexSQL has a few free tools on their site. Before I carry on, I was in no way compensated for this blog post at all. Now that is out of the way, check out ApexSQL tools. I was amazed by the feature richness of these tools. I would be amiss if I didn’t share this with the developer community out there. If you are a developer using SSMS, you definitely must download their free tools and give them a try.
...
These tools are:
  • ApexSQL Complete
    • SSMS and VS integration
    • SQL syntax checking
    • SQL object descriptions
    • SQL code completion
    • SQL code visualization
    • Snippet management
  • ApexSQL Refactor
    • SQL parameter management
    • SQL formatting
    • Consistent code layout
    • Database object refactoring
    • Batch formatting
    • One-to-many relationship replacement
  • ApexSQL Search
    • Smart renaming
    • Text search
    • Database object search
    • Easy SSMS tab navigation
    • SQL code cleaning
    • Graphical dependencies
    Why choose ApexSQL free tools?
    Great software
    We strive to ensure that even though these tools are Free, we still strive for a "Best of Class" product, including, performance, usability, and quality in its respective product class. If you think we can improve our Free tools please contact us to let us know how!
    Feature rich
    Our free tools implement all the features you need for FREE, including SQL formatting, Database object and Text search, Smart renaming, SSMS and Visual Studio integration, SQL refactoring, and much more. These are features that you would actually have to pay for … but don’t have to!
    Continuous development
    Just like all of our other tools, we strive to release updates to our Free SQL tools regularly, fix problems, improve performance, and add features. We look to maintain host integration with new versions of SSMS and Visual Studio when they come out. See What's next, to check out our product roadmap
    Killer support
    Don’t think that because these tools are free that they are unsupported! We still offer Full support via bundle subscriptions including email, phone, and WebEx for all of our Free tools. Even without a subscription to a bundle we are happy to answer questions via our forum and attempt to address any and all issues quickly
    Yes, these tools are really FREE
  • No crippleware, time bombs, or bait and switch
  • No annoying embedded ads or nag screens
  • No additional costs to upgrade to newer versions of SQL Server e.g. 2012, 2014
  • No professional version or non-free features you must pay for
  • No mandatory re-installs
  • No requirement to install additional, non-free software
  • No phone calls from sales people