The Daily Parker

Politics, Weather, Photography, and the Dog

I is for Interface

Blogging A to ZDay 9 of the Blogging A-to-Z challenge brings up one of the key concepts in object-oriented design: the interface.

In object-oriented design, rule #1 is "program to interfaces, not to implementation." In other words, when interacting with an object in your system, you should care about what behaviors and data you need to use, not what the object actually does with them.

Going back to last week's room-and-window example: the original problem was that I want to close all the windows in the house with one method call. The solution on Saturday involved having a Room class that exposed a list of Window objects which you could iterate over and call the Close() method on each.

That's great, but what if I want to close all the windows, doors, fireplaces, and anything else that I can close, because of the zombie apocalypse? In Saturday's implementation, I need to know that rooms have windows, doors, fireplaces, and other things specifically. That is, I need to know how each room is implemented.

I really don't care whether the thing is a window, a door, or a squirrel's mouth; I want it closed now, before the zombies get in.

So let's do this instead: define the behavior of a thing that I can close, and operate on the behavior rather than the thing itself. In C#, I can define an interface, which would look like this (and refer back to Saturday or the code sample file for the rest of the implementation):

namespace InnerDrive.DailyParkerAtoZ.WeekOne
{
    public interface ICloseable
    {
	    void Close();
    }
}

That defines a single behavior that a class can do. (Interfaces can also define data and events, but that's beyond the scope of this post.)

Now I can add the interface to the Window class:

public class Window : ICloseable
{
	public void Close() { }
	public void Open() { }
}

And then refactor the Room class so that you can add and close all manner of closeable things:

public class Room
{
	public void Add(ICloseable closeable)
	{
		_closeableThings.Add(closeable);
	}

	public void CloseEverything()
	{
		foreach (var thing in _closeableThings)
		{
			thing.Close();
		}
	}

	public IEnumerable<ICloseable> Windows => 
		new List<ICloseable>(_closeableThings.Where(p => p is Window));

	private readonly List<ICloseable> _closeableThings = new List<ICloseable>();
}

Well, that looks different. Instead of adding windows to a room, I can now add anything that can be closed. And because of that, at lines 16 and 17, in order to make sure the Windows list still works, I have to change the code so it only returns windows.

It's still a dumb piece of code, but you can start to see how powerful interfaces are. If in the future I create some new class with a Close() method, I can apply the ICloseable interface to it and stick it in a room. (Books, maybe? Escrow accounts? People named Glenn?)

There are many, many implications to all of this. But this is one of the foundations of OO design. I don't care what the thing is, I care what it does or knows. Program to interfaces, not to implementations.

H is for Human Factors

Blogging A to ZThe Blogging A-to-Z challenge enters its second week with a note about you, the human.

Last week I discussed several topics that you probably thought were about computers. They weren't. They were about how you interact with computers.

Computers don't need programming languages. This is a perfectly runnable program for the 6502 microprocessor:

0600: a9 01 8d 00 02 a9 05 8d 01 02 a9 08 8d 02 02

The human-readable version looks like this:

$0600    a9 01     LDA #$01
$0602    8d 00 02  STA $0200
$0605    a9 05     LDA #$05
$0607    8d 01 02  STA $0201
$060a    a9 08     LDA #$08
$060c    8d 02 02  STA $0202

Imagine looking at that all day and trying to debug it. You'd go insane. I know, because back in the day, I wrote that kind of code for 6502 chips and, well, you have evidence about my sanity in these pages.

This is why we use high-level languages instead of low-level ones. We try to abstract away all the crap. Instead of writing for the machine to read, as you do with assembly language (and even there you have a thin abstraction layer), you write software for a human to read.

And the languages continuously improve. Here, below, is some of the first code I ever plagiarized wrote that lived in a production application. You might understand what it does from reading it:

day=VAL(MID$(dtee$,4,2))
month=VAL(LEFT$(dtee$,2))
year=VAL(RIGHT$(dtee$,4))
hour=VAL(LEFT$(ttee$,2))
minute=VAL(MID$(ttee$,4,2))

MDYTOJULIAN:
   julian!=INT(365.2422# * year + 30.44 * (month-1) + day + 1)
   t1=month - 2 - 12 * (month<3)
   t2=year + (month<3)
   t3=INT(t2/100)
   t2=t2-100*t3
   weekday!=INT(2.61*t1-.2) + day + t2 + INT(t2/4)
   weekday! = (weekday! + INT(t3/4) - t3 - t3 + 77) MOD 7 + 1
   t4=julian! - 7 * INT(julian!/7)
   julian!=julian!-t4+weekday!+7*(t4<weekday!-1)+1721060#
   day$=dow$(weekday!)+","+STR$(day)+" "+month$(month)+STR$(year)
   h=hour-12
   IF h<0 THEN julian!=julian!-1:_
      h=h+24
   ju#=CDBL(julian!)
   ju#=ju#+(h/24)+(minute/1440)

That language is called QuickBASIC, which Microsoft published from 1985 until 1991, when Visual BASIC took over. It's a subroutine that converts a date into its Julian day number. I developed it because in QuickBASIC there was no way to do simple date calculations, but in astronomy, there was.

Here's the C# version:

public static double ToJulianDayNumber(this DateTimeOffset date)
{
   return date.ToOADate() + 2415018.5;
}

Forget that this is a naïve implementation, as there are a ton of special cases before the 19th century; and also forget that it uses a magic number that depends on understanding a bit of .NET and Windows internals (like, for example, that JD 2415018.5 is 30 December 1899, which is the epoch date for OLE automation).

The point is, I can abstract away all the calculations and create an extension method which allows me to get any Julian day number just by calling that method on any date-time struct:

var julian = DateTimeOffset.UtcNow.ToJulianDayNumber();

As a human, I'd bet you find that a lot easier to read and understand than the MDYTOJULIAN subroutine above.

But C# makes it even easier to calculate the difference between two dates, obviating the Julian day entirely, unless you're writing software specifically for astronomers:

var otherDay = new DateTimeOffset(2017, 01, 20, 17, 0, 0, TimeSpan.Zero)
var days = DateTimeOffset.Now.Subtract(otherDay).TotalDays;

Because really, you're trying to get the total days between two dates. The Julian day is a required abstraction when you don't have date arithmetic built in. But when you can just do date.Subtract(otherDate) to get a TimeSpan object, the code is a lot easier for humans to read.

Let the compiler worry about the machine. You worry about other humans.

Further reading:

G is for Generics

Blogging A to ZFor day 7 of the Blogging A-to-Z challenge, I'm going totally generic.

A generic in C# allows your code to "defer the specification of one or more types until the class or method is declared and instantiated by client code." In other words, you can declare a class that takes a type to be named later.

Imagine you have a program that represents a house. Your house has rooms, and the rooms have windows, doors, and in some cases, fireplaces. They also have furniture. And sometimes headless corpses. (Don't ask.)

If you were using C# 1.0, you'd need to design structures to hold all of these things, and you'd probably wind up using arrays, like this:

#region Copyright ©2002 Inner Drive Technology

using System.Collections;

#endregion

namespace InnerDrive.DailyParkerAtoZ.WeekOne
{
	public class Window
	{
		public void Close() { }
		public void Open() { }
	}


	public class RoomV1
	{
		public void Add(Window window)
		{
			_windows.Add(window);
		}

		public IEnumerable Windows
		{
			get
			{
				return new ArrayList(_windows);
			}
		}

		private readonly ArrayList _windows = new ArrayList();
	}
}

The only problem is...you don't really know for sure whether the things going into or coming out of the _windows array list are actually windows. That's because the System.Collections.ArrayList class only stores objects, not specific kinds of objects.

Generics allow you to impose type safety on the collection of windows through the use of a type parameter. Now you can do this:

public class Room
{
	public void Add(Window window)
	{
		_windows.Add(window);
	}

	public IEnumerable<Window> Windows => new List<Window>(_windows);

	private readonly List<Window> _windows = new	List<Window>();
}

(Notice also the nifty shorthand on line 8 that eliminates the get method.)

This works because the List<T> class takes any object type for T, leaving it up to the compiler to work out what type it should contain. The prototype for the class looks something like this:

public class List<T>
{
	public void Add(T input) { }
}

The type parameter T can be anything. (You can restrict what T can contain, which I will leave as an exercise for the reader.)

Generics simplify a lot of programming tasks. But just wait until Tuesday when I show you how to make object-oriented designs really fly in C#.

Housekeeping note: The A-to-Z Challenge takes Sundays off. The next post in this series will be on Monday. Enjoy your weekend!

F is for F#

Blogging A to ZWe're up to day 6 of Blogging A-to-Z challenge, FFS.

The last few days I've written about the two main object-oriented languages that come with Visual Studio and .NET: C# and VB.NET. Today I want to diverge just a little into Microsoft's functional language, F#.

At first glance, F# looks a lot like C#. It is, in fact, a flavor of C#; and as it runs on the .NET CLR, it uses .NET constructs. But as Microsoft says, "F# is a programming language that provides support for functional programming in addition to traditional object-oriented and imperative (procedural) programming." Part of this support is the ability to express functions as first-class values. That means you can pass functions around as variables, and do things with them, in ways you can't with C# or other object-oriented languages (sort of—C# can do this too as of 4.7).

Here's an example:

let celsius (f: float) : float = (f - 32.0) * (5.0 / 9.0)

[<EntryPoint>]
let main argv =
    let c = 68.0
    printfn "%f Fahrenheit is %f Celsius" c (celsius c)
    0;;

This is just one step up from "Hello World," in that it actually does something. Two interesting bits: (a) You don't actually need to run this using the EntryPoint identifier; you can run it interactively; and (b) More importantly, celsius is just a variable.

I would love to spend another hour on this post, but I can't do the topic justice. Scott Wlaschin, on the other hand, will show you how to use F# for fun and profit. I recommend his site if you want to learn more.

But here's the sad truth: it's not very practical yet. And C# allows you to pass functions as parameters, even anonymously, so F# no longer has a monopoly on functional programming.

Remember, these A-to-Z posts aren't meant to exhaustively describe the topics. I'm only hoping to outline them and provide some follow-up reading links. And with F#, after a 45 minutes on one post, that's about all I'm up for today.

E is for Encapsulation

Blogging A to ZWelcome to day 5 of the Blogging A-to-Z challenge.

In object-oriented design, we talk about a number of basic concepts that make code easier for humans to read and maintain. Encapsulation is fundamental, by hiding the internal data of a class so that only the class can use it. To access data within the class, you can't just reach in and grab it; you need to use the public properties and methods of the class.

Here's a stupid class:

#region Copyright ©2018 Inner Drive Technology

using System;
using System.Collections.Generic;

#endregion

namespace InnerDrive.DailyParkerAtoZ.WeekOne
{
	public class Encapsulation
	{
		public string Name { get; private set; }

		public void ChangeName(string newName)
		{
			if (string.IsNullOrWhiteSpace(newName))
			{
				throw new ArgumentException("Name must have a value", nameof(newName));
			}
			Name = newName;
			_names.Add(newName);
		}

		internal void Clear()
		{
			Name = string.Empty;
		}

		public IEnumerable<string> NameList => new List<string>(_names);

		private readonly List<string> _names = new List<string>();
	}
}

Seriously, this is dumb. But it demonstrates some of the ways C# encapsulates data.

Line 12 creates a property called Name that any code anywhere can call, because it's public. But it also declares a setter method that is private, meaning only the Encapsulation class itself can set the value of Name.

Lines 14-22 show how this works. The ChangeName method first makes sure you are giving it a real value, then changes Name and adds the new name to a list of names that is itself private. So the only way to change Name is to use the ChangeName method. (There's another way to do this in the property setter, but I wanted to show how this works exactly.)

Lines 24-27 provide you a way of clearing Name, but the method is marked internal. That means only classes in the same assembly can use this method, which has consequences for our unit tests, below.

Line 29 does a nifty trick where, instead of actually giving outside code access to its private list of _names (line 31), it creates a copy of the list and sends that out. Otherwise, anyone would be able to change the contents of _names just by using the NameList property.

Now here's the unit test code:

#region Copyright ©2018 Inner Drive Technology

using System.Linq;
using InnerDrive.DailyParkerAtoZ.WeekOne;
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace InnerDrive.DailyParkerAtoZ.UnitTests
{
	[TestClass]
	public class EncapsulationTests
	{
		[TestMethod]
		public void CanSetNameOfObject()
		{
			var thing = new Encapsulation();
			//thing.Name = "This won't compile";
			//thing._names.Add("This won't compile either");
			thing.ChangeName("Ernie");
			Assert.AreEqual("Ernie", thing.Name);
			Assert.AreEqual(1, thing.NameList.Count());
		}

		[TestMethod]
		public void CanClearNames()
		{
			var thing = new Encapsulation();
			thing.ChangeName("Ernie");
			Assert.AreEqual("Ernie", thing.Name);
			Assert.AreEqual(1, thing.NameList.Count());

			// thing.Clear(); // oops—won't compile!

			// Assertions fail!
			Assert.IsTrue(string.IsNullOrWhiteSpace(thing.Name));
			Assert.AreEqual(1, thing.NameList.Count());
		}
	}
}

The comments explain what's going on.

So how can we test the Encapsulation.Clear() method? By adding this line to the InnerDrive.DailyParkerAtoZ.WeekOne.AssemblyInfo.cs file:

[assembly: InternalsVisibleTo("InnerDrive.DailyParkerAtoZ.UnitTests")]

Now all of the objects, properties, and methods in the WeekOne assembly marked internal are visible to the unit test class, and the tests pass.

Cool, right?

As always, the growing Visual Studio solution is here. The ZIP file contains the complete Git log of the project, by the way. Enjoy.

D is for Database

Blogging A to ZWelcome to day 4 of the Blogging A-to-Z challenge. After yesterday's more theoretical post on the CLR, today will have a practical example of how to connect to data sources from C# applications.

Almost every application ever written needs to store data somewhere. If you're deploying a .NET website into Microsoft Azure (like this blog), you will probably connect it to an Azure SQL Database. Naturally, Visual Studio and C# make this pretty easy.

Here's the code that opens up a database connection and prints out to the Trace window what it's opened:

#region Copyright ©2018 Inner Drive Technology

using System.Configuration;
using System.Data.SqlClient;
using System.Diagnostics;

#endregion

namespace InnerDrive.DailyParkerAtoZ.WeekOne
{
	public static class DataConnections
	{
		private static string ConnectionString => ConfigurationManager.ConnectionStrings["Database"].ConnectionString;

		public static void Connect()
		{
			using (var connection = new SqlConnection(ConnectionString))
			{
				connection.Open();
				Trace.WriteLine($"Connected to {connection.DataSource}");
			}
		}
	}
}

Let's take a look at that line by line.

Lines 3-6 tell the compiler that the objects referenced in the executable code come from those four namespaces (which I'll talk more about on April 16th). The SqlConnection class, for example, lives in the System.Data.SqlClient namespace. If I didn't have the using statement on line 5, I'd have to reference the class and its namespace as System.Data.SqlClient.SqlConnection, which is cumbersome.

Line 13 creates a ConnectionString property that gets its value from a configuration setting. More on that below.

Line 17 first sets up a different kind of using statement, which makes sure that whatever the expensive SqlConnection class does while its alive, it gets cleaned up when it finishes on line 21—even if it throws an exception. Then the same line creates a new SqlConnection object and assigns it to the variable connection.

Line 19 attempts to open the connection to the database. If it succeeds, line 20 prints out the name of the data source. If it fails, it throws an exception that whatever method called this one can catch.

The configuration file looks like this (but with a real database, user ID, and password):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<connectionStrings>
		<add 
			name="Database" 
			connectionString="server={server name}.database.windows.net;initial catalog={database name};persist security info=True;user id={user ID};password={password};"
		/>
	</connectionStrings>
</configuration>

Notice that the name on line 5 corresponds to the configuration setting name on line 13 of the C# code. That's how the code knows which connection string to read from configuration.

Finally, there's also a unit test, which looks like this:

#region Copyright ©2018 Inner Drive Technology

using InnerDrive.DailyParkerAtoZ.WeekOne;
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace InnerDrive.DailyParkerAtoZ.UnitTests
{
	[TestClass]
	public class DataConnectionsTests
	{
		[TestMethod]
		public void CanConnectToDataSource()
		{
			DataConnections.Connect();
		}
	}
}

If the call to DataConnections.Connect() succeeds, the test passes. If the call fails, the test fails and shows the exception that gets thrown.

You can download the code for all of these posts here. You'll have to change the configuration information in the unit test project's app.config file to make it work, of course.

C is for Common Language Runtime

Blogging A to ZDay 3 of the Blogging A-to-Z challenge brings us to the heart of .NET: the Common Language Runtime (CLR).

Microsoft defines the CLR as the run-time environment which "runs the code and provides services that make the development process easier." That isn't the most helpful definition, so let me try to elaborate.

As I described Sunday and yesterday, the .NET compiler takes your source code from C# or whatever other language you use and compiles it down to one or more managed modules containing intermediate language (IL), which get further compiled into assemblies.

When your program runs, the CLR is the thing running it. It loads your assemblies and then handles all the tasks your program needs to survive, like memory management, thread synchronization, exception handling, security, etc. It actually does this through Just-in-Time compilation (JIT), when it translates the IL into your machine's own language. This means that when an IL instruction is executed for the second time, it runs in native CPU code.

The CLR also manages .NET's common type system (CTS), which "defines how types are declared, used, and managed in the common language runtime," according to Microsoft. Types (my topic for April 23rd) are therefore a part of every .NET program, even (gasp!) Ruby.NET. I'm picking on Ruby because in that language, ever instruction gets interpreted at run time, making it possible to use types that you haven't defined. The CLR and the CTS prevent you from doing that.

To learn a lot more about the CLR, I strongly recommend Jeffrey Richter's CLR via C#, which I mentioned Sunday.

B is for BASIC

Blogging A to ZFor day 2 of the Blogging A-to-Z challenge, I'm going to talk about the first computer language I learned, which is still alive and kicking in the .NET universe decades after it first appeared on a MS-DOS 1.0 system disk: BASIC.

BASIC stands for "Beginner's All-Purpose Symbolic Instruction Code." The original specification came from John Kemeny and Thomas Kurtz at Dartmouth College in 1964. Today it's one of the core .NET languages included with Visual Studio as "VB.NET" (for "Visual BASIC," Microsoft's dialect of BASIC released in 1991).

Yesterday I showed you a "Hello, World" application written in C#. (You can download the source code here.)

Here's the VB.NET version:

Module Program

	Sub Main()
		Console.WriteLine("Hello, World!")
		Console.ReadKey()
	End Sub

End Module

What's different? Well, a lot of things: no braces, no include lines, no semicolon line endings...and that's just for a 2-line program.

But look at what's the same. Because this is a .NET program, the actual guts of it look almost exactly the same. There are two calls to different methods on the Console object, and except for the missing semicolons, they are identical to the calls in C#.

Here's the IL:

.method public static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Hello, World!"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_0011:  pop
  IL_0012:  ret
} // end of method Program::Main

Wow. The IL is exactly the same. So both the VB.NET and C# code compile down to functionally identical assemblies.

And that's one of the most important characteristics of .NET: it lets you write code in any language you want (as long as someone has written a compiler for it), and run it on any platform you want (as long as there's a CLR for it).

I worked with Visual BASIC from versions 1 to 6, and then did one project in VB.NET before switching to C# in 2002. You really would need to pay me a lot of money to go back to it. I believe C# is more expressive, more concise, and more able to reflect my intentions than VB.NET.

But there is nothing wrong with VB.NET. If you want to use BASIC, enjoy. With the .NET ecosystem, it's up to you.

A is for Assembly

Welcome to the Daily Parker's 2018 Blogging A-to-Z challenge!

Blogging A to ZWe're starting today with a fundamental concept in Microsoft .NET software development: the Assembly.

Microsoft defines the assembly as "a .dll or .exe file that can contain a collection of APIs that can be called by apps or other assemblies." In other words, an assembly is the basic unit of delivering .NET software to the rest of the world. An assembly "fully describe[s] and contain[s] .NET programs."

When you compile .NET source code, the compiler creates one or more of these files, each of with contains an Intermediate Language (IL) representation of your original code. You can then distribute the .dll or .exe files to any computer that has the correct version of the .NET Common Language Runtime (CLR) installed on it.

I've created a Visual Studio solution for this challenge. Today we're looking just at one small piece of it, which looks like this:

using System;

// ReSharper disable CheckNamespace
namespace InnerDrive.DailyParkerAtoZ.HelloWorld
{
	internal static class Program
	{
		// ReSharper disable once UnusedParameter.Local
		private static void Main(string[] args)
		{
			Console.WriteLine("Hello, World!");
			Console.ReadKey();
		}
	}
}

If you're new to .NET, don't worry about all the pieces. This two-line program compiles into an assembly called HelloWorld.exe, which internally looks like this:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Hello, World!"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_0011:  pop
  IL_0012:  ret
} // end of method Program::Main

Again—we're not going to get into a lot here. Suffice to say, that IL above is what actually lives in the assembly, and what the CLR will execute when you run the program. The assembly also contains a manifest, describing what it contains, and some metadata about its version, author, and whatever else the programming team has added to the assembly info file.

As with all of the topics for this year's A-to-Z challenge, I'm only scratching the surface. There is a ton more to read online and in some solid books on the market. The best information about assemblies I've found is in Jeffrey Richter's CLR via C#.

Note: the Visual Studio Solution for this challenge requires Visual Studio 2017 and the .NET Framework v4.7. ReSharper is also recommended.

Tuesday link round-up

Late afternoon on Tuesday, with so much to do before the end of the week, I can only hope actually to read these articles that have passed through my inbox today:

And now for something completely different tonight: Improv and Arias. Which is why I wonder whether I'll actually get to read all of the articles I just posted about.