Software C# Development | 2017-08-11

Extension methods allow you to add methods to existing types. For a string type, you can add a WordCount function, splitting on ‘ ‘, ‘.’, ‘?’ and putting this method into a similar namespace.

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}

This can be called using

using ExtensionMethods();
string s = “Hello world”
Int i = s.WordCount();

Recommendations

  • Implement extension methods sparingly, only when you have to
  • You can have multiple extension methods in several classes, in a single namespace
  • Extension methods are only brought into scope with a using statement.

Overloaded functions

Allows more than one function of the same name in the same scope which have different argument types. Modifying the return type does not count as having a different signature. Having default values may cause issues because if two methods require default values to be filled in, the compiler will raise an error (ambigous). Named parameters work to specifically use a function.

static void Foo(int x)
{
    Console.WriteLine("Foo(int x)");
}

static void Foo(double y)
{
    Console.WriteLine("Foo(double y)");
}

static void Main()
{
    Foo(y: 10);
}

Recommendations

  • Overloading causes a lot less headache when there is only one method that is applicable.
  • Consider renaming functions to reduce the number of overloaded functions

Async and await

When a function is marked with async it executes normally until it hits the first async, then it schedules itself as a “continuation of the thing being awaited”, once this function runs to completion it returns a task which terminates with a result.

There are several ways to write an async function

  • async Task SomethingAsync() { ... return t; }
    1. Returns a task, producing t
  • async Task SomethingAsync() { ... }
    1. Returns a task, without producing anything, but using await on it you’ll know when it completes.
    2. async void SomethingAsync() { ... }
      1. Does not return a task, no way of knowing when it’s completed. Fire and forget. Everything after the await will run and you don’t know when.
        1. This is used for delagates aka event handlers which have to return void.
        2. Be sure to catch exceptions within the body of the method, but if it’s an anonomous method try catch do not fire.

Anonomous Methods

A way to pass a code block as a delegate parameter. This reduces coding overhead from instanciating delegates because you don’t have to create a separate method

Uses:
  • Initialize a named delegate
  • Pass it as a method parameter

// Declare a delegate.
delegate void Printer(string s);

class TestClass
{
    static void Main()
    {
        // Instantiate the delegate type using an anonymous method.
        Printer p = delegate(string j)
        {
            System.Console.WriteLine(j);
        };

        // Results from the anonymous delegate call.
        p("The delegate using the anonymous method is called.");

        // The delegate instantiation using a named method "DoWork".
        p = new Printer(TestClass.DoWork);

        // Results from the old style delegate call.
        p("The delegate using the named method is called.");
    }

    // The method associated with the named delegate.
    static void DoWork(string k)
    {
        System.Console.WriteLine(k);
    }
}
/* Output:
    The delegate using the anonymous method is called.
    The delegate using the named method is called.
*/