Category Archives: Tips and tricks

C# – Equals() and GetHashCode()

GetHashCode and Equals methods are used to compare objects i.e. when they are inserted into dictionary.
At first GetHashCode is invoked. When object hash code is not colliding – objects are treated as different. If hash codes are the same then Equals method is invoked.
General rule for GetHashCode method impementation: it should always return the same value in the whole object’s lifetime. It means properties used to calculate it should be immutable.
General rule for Equals method implementation: it should check for null and type of compared object.
You always should to implement GetHashCode method when you are overriding Equals method and vice versa.
What’s more when two objects have the same hashcodes, it doesn’t mean that they are identical. But when two objects are identical, they have the same hashcode.

    [TestClass]
    public class EqualsAndGetHashcodeTests
    {

        [TestMethod]
        public void TestComparing()
        {
            var p1 = new Person(1, "John", 1950);
            var p2 = new Person(2, "John", 1960);
            var p3 = new Person(1, "John", 1970);
            var p4 = new Person(1, "John", 1950);

            var people = new HashSet<Person>(); //hash set collects unique elements
            people.Add(p1); //p1 will be added as it is first unique item
            people.Add(p2); //p2 will be added as it has different hash code (equals method won't be called)
            people.Add(p3); //p3 will be added, hashcode is the same as for p1, but Equals method is called and will return false
            people.Add(p4); //p4 won't be added, as hashcode is the same as p1 and Equals method will return true
        }

        private class Person
        {
            public Person(int id, string name, int birthYear)
            {
                Id = id;
                Name = name;
                BirthYear = birthYear;
            }

            public int Id { get; private set; }
            public string Name { get; set; }
            public int BirthYear { get; set; }

            public override bool Equals(object obj)
            {
                if (obj == null)
                    return false;

                if (GetType() != obj.GetType())
                    return false;

                var theOtherPerson = obj as Person;

                return Name == theOtherPerson.Name && BirthYear == theOtherPerson.BirthYear;
            }

            public override int GetHashCode()
            {
                return Id;
            }
        }
    }

Notice that you can easily implement GetHashCode method for anonymous types like this:

            public override int GetHashCode()
            {
                return new { Id, BirthYear }.GetHashCode();
            }

For more about Equals method see: C# – Equals()

OutOfMemoryException – why?

Everybody knows OutOfMemory exception. As name says it is usually thrown when there is no more RAM on the computer, but it is not so clear as there are a few reasons why this exception can occur.

Possible reasons:
* There is no not allocated RAM memory on the computer – it means whole RAM installed on computer is used.
* Limit of the maximum allowed memory usage for a single .NET process is reached. It means that you still have free RAM to use, but single .NET process cannot use more. This limit depends on OS architecture.
* An huge (~2GB) object was trying to be allocated. Notice that .NET has a limit how big a single object can be.
* Too many threads are used in a single process. It means that plenty of RAM can be available, but limit for a number of threads is reached.

Further reading:
* http://stackoverflow.com/questions/13429129/task-vs-thread-differences
* http://stackoverflow.com/questions/13429129/task-vs-thread-differences
* https://support.microsoft.com/en-us/help/2020006/how-to-troubleshoot-out-of-memory-issues-system.outofmemoryexception-in-asp.net

See examples below. I show how some of these problems can be reproduced.

        /// <summary>
        /// Method starts threads one by one. Then there are more than 1000 threads it causes OutOfMemory exception (even when there is still not allocated memory available)
        /// </summary>
        private static void TooManyThreadsCauseOutOfMemory()
        {
            double value = 0;
            for (int i = 0; i <= 2000; i++)
            {
                Thread t = new Thread(() =>
                {
                    while (true)
                    {
                        value = new Random().NextDouble();
                        Thread.Sleep(10000);
                    }
                });
                t.Name = "My thread: " + i;
                t.Start();
            }
        }


        /// <summary>
        /// Opposite to threads, many tasks don't cause strange OutOfMemory exceptions. This can be solution for problem shown in example above.
        /// </summary>
        private static void ManyTasksDontCauseOutOfMemory()
        {
            double value = 0;
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    value = new Random().NextDouble();
                    Thread.Sleep(10000);
                }
            }, TaskCreationOptions.None);
        }


        /// <summary>
        /// Many created objects cause out of memory exception, as there is a limit how much memory can be consumed by a single .NET process.
        /// In my environment when it reaches 1,5GB of memory, exception is thrown.
        /// Notice that I still have free RAM memory on my computer, but a single process has crossed its limit.
        /// </summary>
        private static void ManyObjectsCauseOutOfMemory()
        {
            var cummulativeCollection = new List<byte[]>();
            var sampleCollection = new byte[] { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
            while (true)
            {
                cummulativeCollection.Add(sampleCollection);
            }
        }

Activator

Activator allows you to create instance of an object when class name is unknown in compile time. It can be useful while creating plugins, reading data from external sources (like XML), etc.

See the example below. I have a ‘Person’ class in ‘Common’ library. Person class has got public parameterless constructor.
I can instantiate object of this class from another library (i.e. unit test) passing name of the dll and class (with namespace) in strings to Activator.
Notice: You must reference Microsoft.CSharp library to use ‘dynamic’ keyword.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Windows;

namespace AnyTest
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Windows;

namespace AnyTest
{
    [TestClass]
    public class ActivatorTests
    {
        [TestMethod]
        public void TestMethod1()
        {
            dynamic myPerson = Activator.CreateInstance("Common", "Common.Person").Unwrap();
            Assert.IsTrue(myPerson.Age == 0);
        }
    }
}

C# – Equals()

Equals method behaves differently when speaking about reference types and value types.
Generally equals on reference types compares references. If they are the same true is returned.
Equals on value types compares values in fields. If values are the same true is returned.

    [TestClass]
    public class EqualsTests
    {
        /// <summary>
        /// Reference type
        /// </summary>
        class Cat
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        /// <summary>
        /// Value type
        /// </summary>
        struct Dog
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        [TestMethod]
        public void EqualsTestForReferenceTypes()
        {
            var c1 = new Cat() { Name = "John", Age = 1 };
            var c2 = c1;
            var c3 = new Cat() { Name = "John", Age = 1 };

            var c1c2 = c1.Equals(c2); // true (references are equal)
            var c2c3 = c2.Equals(c3); // false
            var c3c1 = c3.Equals(c1); // false
        }

        [TestMethod]
        public void EqualsTestForValueTypes()
        {
            var d1 = new Dog() { Name = "John", Age = 1 };
            var d2 = d1;
            var d3 = new Dog() { Name = "John", Age = 1 };

            var d1d2 = d1.Equals(d2); // true (values in public and private fields are the same)
            var d2d3 = d2.Equals(d3); // true
            var d3d1 = d3.Equals(d1); // true
        }
    }

Of course, in every class Equals method could be overridden. See string example.

        [TestMethod]
        public void EqualsTestForValueTypes2()
        {
            string s1 = "test";
            string s2 = "test";
            var s1s2 = s1.Equals(s2);// true (despite the fact references are not equal)
        }

Async, await, exception…

Async and await keywords are used to perform asynchronous code. This article shows how to handle exception in such code.
Imagine we have simple application with button. When button is clicked data is read from any external source. We try to make this read asynchronous to not block GUI.

        /// <summary>
        /// Simple button click handler.
        /// </summary>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            
            ReadDataAsync();
        }

        /// <summary>
        /// Simulate data reading (asynchronous).
        /// </summary>
        private async void ReadDataAsync()
        {
            var result = await Task.Run(() =>
            {
                Thread.Sleep(2000);
                return "My data";
            });

            //UI update must be executed on GUI thread
            mainTextBlock.Text = result;
        }

Now imagine that ReadDataAsync throws an exception.
One way to handle this exception is to write catch in ReadDataAsync body.

        /// <summary>
        /// Simple button click handler.
        /// </summary>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ReadDataAsync();
            }
            catch (Exception)
            {
                mainTextBlock.Text = "Reading failed.";
            }
        }

        /// <summary>
        /// Simulate data reading (asynchronous).
        /// </summary>
        private async void ReadDataAsync()
        {
            try
            {
                var result = await Task.Run(() =>
                {
                    throw new Exception("Unknown exception");
                    Thread.Sleep(2000);
                    return "My data";
                });

                //UI update must be executed on GUI thread
                mainTextBlock.Text = result;
            }
            catch (Exception)
            {
                mainTextBlock.Text = "Reading failed.";
            }
        }

Notice, the way shown below is not correct (!) and exception is still not handled. Catch in place where async method is raised won’t fix the problem.

        /// <summary>
        /// Simple button click handler.
        /// </summary>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ReadDataAsync();
            }
            catch (Exception)
            {
                mainTextBlock.Text = "Reading failed.";
            }
        }

        /// <summary>
        /// Simulate data reading (asynchronous).
        /// </summary>
        private async void ReadDataAsync()
        {
                var result = await Task.Run(() =>
                {
                    throw new Exception("Unknown exception");
                    Thread.Sleep(2000);
                    return "My data";
                });

                //UI update must be executed on GUI thread
                mainTextBlock.Text = result;
        }

Notice, that if we change the ReadDataAsync return type from void to Task, the exception will be swallowed, nevertheless we don’t have catch anywhere. We won’t know what is the type of the exception etc.

        /// <summary>
        /// Simple button click handler.
        /// </summary>
        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ReadDataAsync();
            }
            catch (Exception)
            {
                mainTextBlock.Text = "Reading failed.";
            }
        }


        /// <summary>
        /// Simulate data reading (asynchronous).
        /// </summary>
        private async Task ReadDataAsync()
        {
            var result = await Task.Run(() =>
            {
                throw new Exception("Unknown exception");
                Thread.Sleep(2000);
                return "My data";
            });

            //UI update must be executed on GUI thread
            mainTextBlock.Text = result;
        }

But we can solve the problem. Generally we should avoid async void methods, always when possible, to get rid of such behaviour. Let’s change the code above to edit the return type of our method to async Task. Then await method and catch possible exceptions.

        /// <summary>
        /// Simple button click handler.
        /// </summary>
        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var data = await ReadDataAsync();
                //update GUI on UI thread
				mainTextBlock.Text = data;
            }
            catch (Exception)
            {
                mainTextBlock.Text = "Reading failed.";
            }
        }

        /// <summary>
        /// Simulate data reading (asynchronous).
        /// </summary>
        private async Task<string> ReadDataAsync()
        {
            var result = await Task.Run(() =>
            {
                throw new Exception("Unknown exception");
                Thread.Sleep(2000);
                return "My data";
            });

            return result;
        }

Exceptions in tasks

A few examples show application behaviour when we have exception in task. Comments describe what happen in specific situations and how to cope with exceptions.

Example A.

        /// <summary>
        /// Method shows how exception from task is swallowed.
        /// </summary>
        internal static void TaksWithException()
        {
            //exception is swallowed
            //failure will not be visible as noone asks for result of the task
            //task is faulted
            var tA = new Task<int>(() =>
            {
                Console.WriteLine("Task A");
                throw new Exception("Unknown exception");
                return 1;
            });

            tA.ContinueWith((t) =>
            {
                if (t.IsFaulted)
                    Console.WriteLine("Task faulted.");
                else
                    Console.WriteLine("Task completed.");
            });

            tA.Start();
        }

Example B.

        /// <summary>
        /// Method shows how exception is not thrown until result is accessed.
        /// </summary>
        internal static void TaksWithException1()
        {
            //exception is unhandled
            //task is faulted
            //unhandled exception will be visible as we try to display result of the task.
            var tA = new Task<int>(() =>
            {
                Console.WriteLine("Task A");
                throw new Exception("Unknown exception");
                return 1;
            });

            tA.ContinueWith((t) =>
            {
                if (t.IsFaulted)
                    Console.WriteLine("Task faulted.");
                else
                    Console.WriteLine("Task completed.");
            });

            tA.Start();

            Console.WriteLine(tA.Result); //here exception is thrown
        }

Example C.

        /// <summary>
        /// Method shows how exception is handled in task body.
        /// </summary>
        internal static void TaksWithException2()
        {
            //exception is catched
            //task is not faulted
            //valid result is returned
            var tA = new Task<int>(() =>
            {
                try
                {
                    Console.WriteLine("Task A");
                    throw new Exception("Unknown exception");
                }
                catch (Exception)
                {
                    Console.WriteLine("Exception caught in catch.");
                }
                return 1;
            });

            tA.ContinueWith((t) =>
            {
                if (t.IsFaulted)
                    Console.WriteLine("Task faulted.");
                else
                    Console.WriteLine("Task completed.");
            });

            tA.Start();

            Console.WriteLine(tA.Result);
        }

Example D.

        /// <summary>
        /// Method shows how exception is handled when accessing the result in continuation method
        /// </summary>
        internal static void TaksWithException3()
        {
            //exception is not catched, but is not visible until task result is not accessed
            //task is faulted
            //AggregateException is catched when result is accessed
            var tA = new Task<int>(() =>
            {
                Console.WriteLine("Task A");
                throw new Exception("Unknown exception");
                return 1;
            });

            var tB = tA.ContinueWith((t) =>
            {
                if (t.IsFaulted)
                    Console.WriteLine("Task faulted.");
                else
                    Console.WriteLine("Task completed.");
            });

            tB.ContinueWith((t) =>
            {
                try
                {
                    Console.WriteLine(tA.Result);
                }
                catch (AggregateException ae)
                {
                    ae.Handle((e) =>
                    {
                        if (e is NullReferenceException)
                        {
                            Console.WriteLine("NullReferenceException in task handled when accessing the result");
                            return true;
                            }
                        else
                        {
                            Console.WriteLine("Other exception in task handled when accessing the result");
                            return true;
                        }
                    });
                }
                catch (Exception)
                {
                    Console.WriteLine("Exception in task handled when accessing the result");
                }
            });

            tA.Start();
        }

Example E.

        /// <summary>
        /// Method shows how to run appropriate continuation method when task has faulted.
        /// </summary>
        internal static void TaksWithException4()
        {
            //exception is not catched, but is not visible until task result is not accessed
            //task is faulted
            //appropriate continuation method is executed
            var tA = new Task<int>(() =>
            {
                Console.WriteLine("Task A");
                throw new Exception("Unknown exception");
                return 1;
            });

            tA.ContinueWith((t) =>
            {
                Console.WriteLine("Task completed.");
            }, TaskContinuationOptions.OnlyOnRanToCompletion);

            tA.ContinueWith((t) =>
            {
                Console.WriteLine("Task faulted.");
                if (t.Exception != null && t.Exception.InnerExceptions != null)
                {
                    foreach(var e in t.Exception.InnerExceptions)
                    {
                        Console.WriteLine(e.Message);
                    }
                }

            }, TaskContinuationOptions.OnlyOnFaulted);

            tA.Start();
        }

DebuggerDisplay & DebuggerTypeProxy

There are a few options to make debugging simpler, for example by displaying data in better way. Two of them are explained below.

1. DebuggerDisplay attribute on Employee class decides how variables are presented during debugging. We declare in the attribute a string used to display variable in i.e. watch window.

//the way how variable is presented during debugging

    [DebuggerDisplay("Employee: {Name}, {Age} years old.")]
    class Employee
    {
        public Employee(string name, int age)
        {
            Name = name;
            Age = age;
            Skills = new List<Skill>();
        }

        public string Name { get; set; }
        public int Age { get; set; }
        public List<Skill> Skills { get; set; }
    }

The result of the code above is presented below.
debuggerdisplay0

2. DebuggerTypeProxy attribute allows us to use additional proxy class to decide what is displayed during debugging. Notice that I wrote internal EmployeeDebuggerProxy class which exposes two properties calculated somehow on _employee instance. This proxy class is used in DebuggerTypeProxy attribute on Employee class.

// use proxy class to present data during debugging
    [DebuggerTypeProxy(typeof(EmployeeDebuggerProxy))] 
    class Employee
    {
        public Employee(string name, int age)
        {
            Name = name;
            Age = age;
            Skills = new List<Skill>();
        }

        public string Name { get; set; }
        public int Age { get; set; }
        public List<Skill> Skills { get; set; }

        internal class EmployeeDebuggerProxy
        {
            private Employee _employee;

            public EmployeeDebuggerProxy(Employee e)
            {
                _employee = e;
            }

            ///<summary>
            /// Gets the name and age of the employee.
            /// </summary>
            public string DisplayName
            {
                get
                {
                    return String.Format($"{_employee.Name} ({_employee.Age})");
                }
            }

            ///<summary>
            /// Gets the most important skill of employee.
            /// </summary>
            public string TopSkill
            {
                get
                {
                    return _employee.Skills
                        .OrderByDescending(s => s.YearsOfExperience)
                        .FirstOrDefault().Technology;
                }
            }
        }
    }

    ///<summary>
    /// Helper class to present employee's skills.
    /// </summary>
    class Skill
    {
        public string Technology { get; set; }
        public int YearsOfExperience { get; set; }
    }

The result during debugging.

debuggertypeproxy