Programming Paradigms

Web page by Kevin Harris of Homer IL

Please contact Kevin Harris of Homer IL concerning this web site

Programming Paradigms

Language Integrated Query (LINQ) extends the data querying capabilities of programming languages and provides a common way to access data from various sources (databases, XML, collections, etc.). LINQ was released as part of .NET 3.5 (11/19/2007) and ports also exist for various non-.NET languages such as Java, PHP, JavaScript, and ActionScript. LINQ consists of two types of syntax: Query Syntax (resembling SQL) and Method Syntax (allows method chaining). LINQ makes use of lambda expressions, anonymous types, and object initializers.


LINQ

LINQ includes over 50 query operators for functions such as filtering, grouping, aggregations, partitioning, and projection. LINQ makes heavy use of generic interfaces and extension methods to provide these functions. For example, LINQ contains the ISequence<T> which hides the data source, which could be a database, file, or in-memory collection). While interfaces work well for hiding the data source, it requires full implementation of all its method signatures. So adding a new method breaks an existing application which uses the interface. To prevent this Microsoft introduced Extension Methods which allows methods to be created, and used, as if belong to an existing type, but in reality they are static methods which belong to a different type.

Extension Methods are static methods in static classes which allow the extension of any type (e.g. can even extend sealed classes). However through the use of the this keyword, the extension methods appear as if they are an instance method of the type. For example, the following static method determines the number of days until the end of the year.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;

namespace ExtensionMethods
{
    public class Program
    {
        public static void Main(string[] args)
        {
            int days = DateTimeUtilities.DaysTilEndOfYear(DateTime.Now);
            Console.WriteLine($"Days until end of year: {days}");
            Console.ReadLine();
        }
    }

    public static class DateTimeUtilities
    {
        public static int DaysTilEndOfYear(DateTime date)
        {
            int daysInYear = 365;
            if (DateTime.IsLeapYear(DateTime.Now.Year))
                daysInYear++;
            return daysInYear - DateTime.Now.DayOfYear;
        }

    }
}


Adding the this keyword in the parameter list, before the type it is modifying, makes it an extension method which now appears in intellisense as if it were an instance method on the type. It can now be invoked in the same way as instance methods of the type.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;

namespace ExtensionMethods
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //int days = DateTimeUtilities.DaysTilEndOfYear(DateTime.Now);
            int days = DateTime.Now.DaysTilEndOfYear();
            Console.WriteLine($"Days until end of year: {days}");
            Console.ReadLine();
        }
    }

    public static class DateTimeUtilities
    {
        public static int DaysTilEndOfYear(this DateTime date)
        {
            int daysInYear = 365;
            if (DateTime.IsLeapYear(DateTime.Now.Year))
                daysInYear++;
            return daysInYear - DateTime.Now.DayOfYear;
        }

    }
}




Extensions methods are a compiler trick which makes the method appear in intellisense and allows the static method be be invoked the same way as an instance method.

.Adding this Keyword to Make an Extension Method


Adding this Keyword to Make an Extension Method


Below is another example of an extension method. This extension method returns on the words from an IEnumerable which contain more than one vowel.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Collections.Generic;

namespace ExtensionMethods
{
    public class Program
    {
        public static void Main(string[] args)
        {
            IEnumerable<string> names = new[] { "Kevin", "Cathy", "Suzy", "Tessa", "Shadow" };

            IEnumerable<string> singleVowelNames = names.HasSingleVowel();

            foreach (var n in singleVowelNames)
            {
                Console.WriteLine($"Single Vowel Name: {n}");
            }
            Console.ReadLine();
        }
    }

    public static class QueryExtensions
    {
        public static IEnumerable<string> HasSingleVowel(this IEnumerable<string> words)
        {            
            foreach (var w in words)
            {
                int vowelCount = 0;
                if (w.ToUpper().Contains("A")) vowelCount++;
                if (w.ToUpper().Contains("E")) vowelCount++;
                if (w.ToUpper().Contains("I")) vowelCount++;
                if (w.ToUpper().Contains("O")) vowelCount++;
                if (w.ToUpper().Contains("U")) vowelCount++;
                if (vowelCount == 1)
                    yield return w;
            }
        }
    }

}


Extension Method Returning Words With More Thane One Vowel

All the LINQ methods are defined as extension methods in the System.Linq namespace. By using the free standalone .NET decompiler dotPeek from JetBrains, you can view the definitions of the LINQ methods (see image below). LINQ methods work with the Enumerable class which implements the IEnumerable<TSource> generic interface. The TSource defines the WHERE the data is coming from, but the programmer must specify HOW the data is to be manipulated. The HOW to define the data is passed to the LINQ method as a delegate (i.e. pointer to a method). The shorthand way of defining delegates inline, know as Lambda Expressions, is frequently used in LINQ methods to define HOW the data is to be manipulated.

Note: As Bill Wagner points out, IEnumerable is not a collection. Bill uses his deck of cards analogy to illustrate that IEnumerable is a sequence, i.e. you get one card at a time as opposed to getting the entire deck at once. This is very significant when working with large data sets. So the LINQ methods are not returning a set of values, but instead are returning the next value in a sequence of values. See

.JetBrains dotPeek Showing LINQ Classes


JetBrains dotPeek Showing LINQ Classes

Lambda Expressions

The following code rewrites the example above to use a delegate to pass into the extension method a method which determines if an item from the enumeration contains only a single vowel. That is the "ContainsVowels" method returns true if the input string contains just a single vowel.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections.Generic;

namespace ExtensionMethods
{
    public class Program
    {
        public static void Main(string[] args)
        {
            IEnumerable<string> names = new[] { "Kevin", "Cathy", "Suzy", "Tessa", "Shadow" };

            //IEnumerable<string> singleVowelNames = names.HasSingleVowel();

            IEnumerable<string> singleVowelNames = names.MyFilter(ContainsVowels);

            foreach (var n in singleVowelNames)
            {
                Console.WriteLine($"Single Vowel Name: {n}");
            }
            Console.ReadLine();
        }

        static bool ContainsVowels(string s)
        {
            int vowelCount = 0;
            if (s.ToUpper().Contains("A")) vowelCount++;
            if (s.ToUpper().Contains("E")) vowelCount++;
            if (s.ToUpper().Contains("I")) vowelCount++;
            if (s.ToUpper().Contains("O")) vowelCount++;
            if (s.ToUpper().Contains("U")) vowelCount++;
            if (vowelCount == 1)
                return true;
            else
                return false;
        }
    }

}

public static class QueryExtensions
{
    public static IEnumerable<T> MyFilter<T>(this IEnumerable<T> words, MyDelegate<T> MyPredicate)
    {
        foreach (var w in words)
        {
            if (MyPredicate(w))
                yield return w;
        }
    }

    public delegate bool MyDelegate<T>(T item);
}


The delegate allows different methods to be passed into the extension method which can vary the logic used to select an item from the enumeration. As shown in the code below, the "ContainH" method is now passed into the extension method to search for words which contains an "H", instead of searching for words which contain a vowel.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System;
using System.Collections.Generic;

namespace ExtensionMethods
{
    public class Program
    {
        public static void Main(string[] args)
        {
            IEnumerable<string> names = new[] { "Kevin", "Cathy", "Suzy", "Tessa", "Shadow" };

            //IEnumerable<string> singleVowelNames = names.HasSingleVowel();

            IEnumerable<string> resultNames = names.MyFilter(ContainsH);

            foreach (var n in resultNames)
            {
                Console.WriteLine($"Name contains an H: {n}");
            }
            Console.ReadLine();
        }

        static bool ContainsVowels(string s)
        {
            int vowelCount = 0;
            if (s.ToUpper().Contains("A")) vowelCount++;
            if (s.ToUpper().Contains("E")) vowelCount++;
            if (s.ToUpper().Contains("I")) vowelCount++;
            if (s.ToUpper().Contains("O")) vowelCount++;
            if (s.ToUpper().Contains("U")) vowelCount++;
            if (vowelCount == 1)
                return true;
            else
                return false;
        }

        static bool ContainsH(string s)
        {
            int hCount = 0;
            if (s.ToUpper().Contains("H")) hCount++;
            if (hCount > 0)
                return true;
            else
                return false;
        }

    }

}

public static class QueryExtensions
{
    public static IEnumerable<T> MyFilter<T>(this IEnumerable<T> words, MyDelegate<T> MyPredicate)
    {
        foreach (var w in words)
        {
            if (MyPredicate(w))
                yield return w;
        }
    }

    public delegate bool MyDelegate<T>(T item);
}


Instead of passing in the method signature, an anonymous delegate could be used as shown in the code below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections.Generic;

namespace ExtensionMethods
{
    public class Program
    {
        public static void Main(string[] args)
        {
            IEnumerable<string> names = new[] { "Kevin", "Cathy", "Suzy", "Tessa", "Shadow" };

            //IEnumerable<string> singleVowelNames = names.HasSingleVowel();

            IEnumerable<string> resultNames = names.MyFilter(delegate (string s)
                                                            {
                                                                return s.ContainsH();
                                                            });

            foreach (var n in resultNames)
            {
                Console.WriteLine($"Name contains an H: {n}");
            }
            Console.ReadLine();
        }
    }

}

public static class QueryExtensions
{
    public static IEnumerable<T> MyFilter<T>(this IEnumerable<T> words, MyDelegate<T> MyPredicate)
    {
        foreach (var w in words)
        {
            if (MyPredicate(w))
                yield return w;
        }
    }

    public delegate bool MyDelegate<T>(T item);

    public static bool ContainsH(this String s)
    {
        int hCount = 0;
        if (s.ToUpper().Contains("H")) hCount++;
        if (hCount > 0)
            return true;
        else
            return false;
    }

}


The anonymous delegate in the above code can be replaced with the lambda expression as shown in the code below on line 14.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
using System.Collections.Generic;

namespace ExtensionMethods
{
    public class Program
    {
        public static void Main(string[] args)
        {
            IEnumerable<string> names = new[] { "Kevin", "Cathy", "Suzy", "Tessa", "Shadow" };

            //IEnumerable<string> singleVowelNames = names.HasSingleVowel();

            IEnumerable<string> resultNames = names.MyFilter(s => s.ContainsH());

            foreach (var n in resultNames)
            {
                Console.WriteLine($"Name contains an H: {n}");
            }
            Console.ReadLine();
        }
    }

}

public static class QueryExtensions
{
    public static IEnumerable<T> MyFilter<T>(this IEnumerable<T> words, MyDelegate<T> MyPredicate)
    {
        foreach (var w in words)
        {
            if (MyPredicate(w))
                yield return w;
        }
    }

    public delegate bool MyDelegate<T>(T item);

    public static bool ContainsH(this String s)
    {
        int hCount = 0;
        if (s.ToUpper().Contains("H")) hCount++;
        if (hCount > 0)
            return true;
        else
            return false;
    }

}


Func, Action, and Expressions

Func is a generic type which encapsulates delegates, i.e. encapsulates callable code. Func takes 1 to 16 generic parameters with the last parameter indicating the return type and the other parameters indicating the input types. For example a function which calculates the volume of an object could be coded as:

1
2
            Func<int,int,int,int> calcVolume = (l,w,h) => l * w * h;
            Console.WriteLine($"Volume is: {calcVolume(2,3,4)}");


Action is similar to func ad it defines callable code. Except Action does not return a value; An example of an action is:

1
2
            Action<string> writeName = x => Console.WriteLine(x);
            writeName("Kevin Harris");


With Func the delegate definition is no longer needed. The code below shows how the delegate definition can be eliminated when Func is used.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public static class QueryExtensions
{
    //public static IEnumerable<T> MyFilter<T>(this IEnumerable<T> words, MyDelegate<T> MyPredicate)
    public static IEnumerable<T> MyFilter<T>(this IEnumerable<T> words, Func<T,bool> MyPredicate)
    {
        foreach (var w in words)
        {
            if (MyPredicate(w))
                yield return w;
        }
    }
    // Not needed when using Func
    //public delegate bool MyDelegate<T>(T item);

}

When LINQ operators are used against data which is not in memory, which may be out of process, perhaps even on another machine, such as when running against a database server or a web service ... they are wrapped in expressions to create an Expression Tree. Expression trees were created to make the task of converting code, such as query expressions, into a string which is passed to some other process for execution. When a LINQ expression is executed against a database, such as Oracle, it is Oracle which provides the code to translate the LINQ into SQL to execute against the database. With the LINQ expression represented by an expression tree, Oracle can accept and interpret the LINQ expression and determine the best way to convert it into SQL that the Oracle database understands.

LINQ to Objects returns IENumerable, while LINQ to SQL, or LINQ to Entities, returns IQueryable. IQueryable makes use of expression trees (to run the LINQ query on a remote source), while LINQ to Objects typically do not because they run the LINQ query against objects in memory.

Expression trees represent code in a tree-like data structure. This allows dynamic modification of executable code and is used to execute LINQ queries against databases. Expression trees are also used by the Dynamic Language Runtime (DLR) to create dynamic objects which can be used together with static objects. This enables dynamic features in statically typed languages, such as C# and VB. For example C# and VB use dynamic objects for HTML, DOM, and reflection.

.Expression Tree Viewer in Visual Studio


Expression Tree Viewer in Visual Studio

Dynamic Language Runtime

The Dynamic Language Runtime (DLR) runs on top of the Common Language Runtime (CLR) and supports dynamic language features. The DLR was incorporated into .NET 4.0 in April 2010. The DLR allows .NET to support dynamic languages such as IronPython and IronRuby. It also allows statically-typed languages, such as C# and VB to support dynamic features. Note, the DLR is similar in concept to Sun Microsystems' Da Vinci Machine project which extended the Java Virtual Machine to support dynamic languages.

.Dynamic Language Runtime


Dynamic Language Runtime

Typically languages are divided into one of two categories: Static (C/C++, Java, C#, F#, Haskell) or Dynamic (JavaScript, Ruby, Python, PHP, Perl). But sometimes the distinction is blurred as some languages, such as C#, support both features. Typically dynamic language allow you to modify types and code at runtime. Dynamic languages do not have a pre-runtime compiler phase so type checking is performed when the program runs, if at all. In a Static languages are strongly typed so you can not perform operations, such as assign a string value to an integer, or dynamically change the definition of a class, as these will perform compiler errors. However in a dynamic language, such as Ruby, these operations are allowed.

Static type checking finds typing errors early, at compile time, instead of later at run time. However this does pose some limitations upon the language, which forces the use of reflection to perform some operations. Before the DLR, it was difficult for .NET languages to interoperate with dynamic languages or COM objects (the dominate Microsoft component technology prior to .NET). An example of this difficulty was evident when programming with COM components to automate Microsoft Word or Excel.

In C# 4.0 the dynamic keyword was introduced for typing variables. When the C# compiler sees a dynamically typed variable, it turns off all compile time checks for that variable. Any operations performed on a dynamically typed variable are resolved at run time. Some times dynamics can eliminate the need for type casting or use of reflection (e.g. GetMember(), GetMethod(), GetProperty()). For example if you do not know the type of an object, but you know the name of its method you wish to invoke, you can use reflection, as shown below. Or more simply you can eliminate the reflection code when using dynamic, also shown below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Reflection;

namespace DynamicExample
{
    public class Program
    {
        public static void Main(string[] args)
        {

            // Invoke using Reflection
            //object o = GetMysteryObject();
            //o.GetType().GetMethod("Work").Invoke(o, null);

            // Invoke Dynamically Instead of using Reflection
            dynamic o = GetMysteryObject();
            o.Work();
        }

        private static object GetMysteryObject()
        {
            return new MysteryClass { Name = "Kevin" };
        }
    }

    public class MysteryClass
    {
        public string Name { get; set; }

        public void Work()
        {
            Console.WriteLine($"{Name} : work, work, work");
            Console.ReadLine();
        }
    }

}


Calling Method on Unknown Type using Reflection vs Dynamic

Dynamic can be used to interoperate with COM objects, as show in the code below which creates and populates an Excel spreadsheet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace ComInteropExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Type excelType = Type.GetTypeFromProgID("Excel.Application");
            dynamic excel = Activator.CreateInstance(excelType);

            // Use excel API
            excel.Visible = true;
            excel.Workbooks.Add();
            dynamic sheet = excel.ActiveSheet;

            sheet.Cells[1, "A"] = "Process Name";
            sheet.Cells[1, "B"] = "Start Time";
            sheet.Cells[1, "C"] = "Total Processor Time";

            Process[] processes = Process.GetProcesses();
            for (int i = 0; i < processes.Length; i++)
            {
                if (processes[i].ProcessName != "Idle")
                {
                    sheet.Cells[i + 2, "A"] = processes[i].ProcessName;
                    sheet.Cells[i + 2, "B"] = processes[i].StartTime.ToString();
                    sheet.Cells[i + 2, "C"] = processes[i].TotalProcessorTime.ToString();
                }
            }

        }
    }
}


Using dynamic to Create and Populate an Excel Spreadsheet

Func Examples

Declare a Func variable and assign it a lambda expression.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Collections.Generic;
using System.Linq;

namespace FuncExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // Declare a Func variable and assign a lambda expression to it.
            Func<string, string> MyToUpperCase = s => s.ToUpper();

            // Create a list of string containing the names of colors.
            List<String> colors = new List<String> { "blue", "Green", "BLACK", "oRange" };

            // Query the list and convert to upper case.
            IEnumerable<String> theColors = colors.Select(MyToUpperCase);

            // Write the converted string values.
            foreach (var s in theColors)
            {
                Console.WriteLine($"The color is: {s}");              
            }
            Console.ReadLine();
        }
    }
}


Example Usage of a Func Variable

Example of a Func used to create a predicate (function which returns a boolean). The predicate is used to select particular strings and is used with a static method to filter an enumeration of strings.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Collections.Generic;
using System.Linq;

namespace FuncExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // Declare a Func variable and assign a lambda expression to it.
            Func<string, string> MyToUpperCase = s => s.ToUpper();

            // Create a list of string containing the names of colors.
            List<String> colors = new List<String> { "blue", "Green", "BLACK", "oRange" };

            // Query the list and convert to upper case.
            IEnumerable<String> theColors = colors.Select(MyToUpperCase);

            // Write the converted string values.
            foreach (var s in theColors)
            {
                Console.WriteLine($"The color is: {s}");              
            }
            Console.ReadLine();
        }
    }
}


Func used to create a predicate, used with static method to filter an enumeration of strings.


References


Top