Writing Implicit and Explicit C# Conversion Operators

When writing custom classes we can provide behaviour to allow for both explicit and implicit conversions to other types.

Implicit conversion operators are those that don’t require an explicit cast.

Explicit conversion operators are those that do require an explicit cast.

As an example, the following code shows a simple console application to covert a weight in Pounds to Kilograms.

internal class Program
{
    private static void Main(string[] args)
    {
        WriteLine("Please enter a value in lbs");
        var lbsText = ReadLine();

        var lbs = new PoundsExplicit(float.Parse(lbsText));
        WriteLine($"\nYou entered {lbs}");

        Kilogram kg = (Kilogram) lbs;
        WriteLine($"\n{lbs} is {kg}");

        WriteLine("\nPress enter to exit");
        ReadLine();
    }
}

Notice in the preceding code the line Kilogram kg = (Kilogram) lbs; is explicitly casting from a type of PoundsExplicit to Kilograms.

The Kilogram class is defined as follows:

internal class Kilogram
{
    public float Weight { get; set; }

    public Kilogram(float weight)
    {
        Weight = weight;
    }

    public override string ToString()
    {
        return $"{Weight} kg";
    }
}

To allow the (explicit) cast from PoundsExplicit to Kilogram, the PoundsExplicit class defines an explicit conversion operator as shown in the following code:

internal class PoundsExplicit
{
    public float Weight { get; set; }

    public PoundsExplicit(float weight)
    {
        Weight = weight;
    }
    public override string ToString()
    {
        return $"{Weight} lbs";
    }

    public static explicit operator Kilogram(PoundsExplicit lbs)
    {
        const float conversionRate = 0.45359237f;

        float equivalentKgs = lbs.Weight * conversionRate;

        return new Kilogram(equivalentKgs);
    }
}

To allow the conversion to Kilogram to be implicit, with no cast required (e.g. Kilogram kg = lbs;) the operator can be changed to implicit as shown in the following class:

internal class PoundsImplicit
{
    public float Weight { get; set; }

    public PoundsImplicit(float weight)
    {
        Weight = weight;
    }       

    public override string ToString()
    {
        return $"{Weight} lbs";
    }

    public static implicit operator Kilogram(PoundsImplicit lbs)
    {
        const float conversionRate = 0.45359237f;

        float equivalentKgs = lbs.Weight * conversionRate;

        return new Kilogram(equivalentKgs);
    }
}

The main method can now be modified as follows:

private static void Main(string[] args)
{
    WriteLine("Please enter a value in lbs");
    var lbsText = ReadLine();

    var lbs = new PoundsImplicit(float.Parse(lbsText));
    WriteLine($"\nYou entered {lbs}");

    Kilogram kg = lbs;
    WriteLine($"\n{lbs} is {kg}");

    WriteLine("\nPress enter to exit");
    ReadLine();
}

Notice in the preceding code the conversion from PoundsImplicit to Kilogram now is implicit, it does not require an explicit cast.

When deciding between implicit or explicit conversion operators you should consider the resulting readability of code that uses the types. An implicit cast is more convenient whereas an explicit cast may add extra clarity/readability to the code that uses the types.

New FeatureToggle Release: v3.4 With Fluent Syntax

FeatureToggle is an open source feature toggling / feature switching library for .NET.

Version 3.4 Introduces an new additional way to get the value of whether a toggle is enabled or not.

In versions to v3.3 and earlier, to get the value of a toggle, an instance of the toggle class needed to be created manually:

new SampleFeatureToggle().FeatureEnabled

With v3.4 a new additional fluent way is introduced to improve readability and offer a convenience when evaluating a toggle.

First reference the FeatureToggle.Core.Fluent namespace, then the Is<T> class can be used as follows:

Is<SampleFeatureToggle>.Enabled
Is<SampleFeatureToggle>.Disabled

To make the fluent style a little more readable, the name of the concrete toggle class can be shorted, so rather than PrintFeatureToggle for example, it could be named Print, the code would then read:

Is<Printing>.Enabled
Is<Printing>.Disabled

New Pluralsight Course: Automated Business Readable Web Tests with Selenium and SpecFlow

SpecFlow is a tool that can translate natural language scenarios (e.g. writing in English or other spoken languages) into test code. This can allow business people, users, or other stakeholders to verify that the correct features are being built.

Selenium is a tool that allows test code (multiple programming languages supported) to automated a web browser. This allows the creation of automated UI tests that operate the web application as if an end user where doing it; for example clicking buttons and typing text into input boxes.

My new Pluralsight course shows how to integrate these two tools.

The course is organized into four modules:

  1. Introduction to Business Readable Web Testing
  2. Getting Started with Selenium
  3. Adding Business Readability with SpecFlow
  4. Creating More Maintainable Web Automation

If you’re new to SpecFlow I suggest watching this course first before moving on to Automated Business Readable Web Tests with Selenium and SpecFlow.

Free eBook C# 6.0: What’s New Quick Start Complete

free C# bok cover image

My new free eBook “C# 6.0: What’s New Quick Start” is now complete and available for download.

The book covers the following:

  • Using Static Type Directive
  • String Interpolation
  • The Null-Conditional Operators
  • Getter Only Auto Properties
  • Using Await in Catch and Finally Blocks
  • Property, Dictionary, and Index Initializers
  • The nameof Operator
  • Expression Bodied Functions and Properties
  • Exception Filters
  • Visual Studio 2015 and C# 6

You can download it for free or pay what you think it is worth.

Happy reading!

New Pluralsight Course: Business Readable Automated Tests with SpecFlow 2.0

My newest Pluralsight course was just published. Business Readable Automated Tests with SpecFlow 2.0 teaches how to create tests that the business can read, understand, and contribute to. These “English-like” tests (other spoken languages are supported) can be executed by writing test code that is associated with the “English-like” steps. Because the tests sit alongside the source code, they can become living (executable) documentation for the system, as opposed to an out-of-date Word document somewhere on the network for example. Check out the course here.

New Free eBook C# 6.0: What’s New Quick Start

C# 6 eBook Cover Image

The first chapters of my new free eBook have just been published.

The book will cover the new features added in C# 6.0 and provide a quick start to those new to version 6 or as a handy reference to those already using C# 6.0

New chapters are being added periodically and you can get the version now and get access to new chapters as they are published.

You can download the book for free or pay what you think it’s worth.

FeatureToggle v3.3 Released

FeatureToggle is an open source feature toggling library for .NET.

Version 3.3 was just released to NuGet and includes two minor new features as described below.

FallbackValueDecorator

The FallbackValueDecorator allows you to wrap (decorate) a primary toggle and specific a fallback toggle to be used if the primary toggle fails or is not configured.

new FallbackValueDecorator(new MyPrimaryToggle(), new MyFallbackToggle());

An optional overload allows the specifying of an Action<Exception> to be called if the primary toggle errors for example to perform some logging or alerting:

public FallbackValueDecorator(IFeatureToggle primaryToggle, IFeatureToggle fallbackToggle, Action<Exception> logAction = null)

CompositeOrDecorator

The CompositeOrDecorator allows the specification of two toggle instances, if either one of the toggles is enabled the decorator will return true:

new CompositeOrDecorator(new AnEnabledFeature(), new ADisabledFeature());


If you’re new to the concept of feature toggling or FeatureToggle check out my Pluralsight course Implementing Feature Toggles in .NET with FeatureToggle or the documentation.


Thanks to Craig Vermeer for the work investigating failing convention tests in VS2015 for this release.

New Pluralsight Course: Getting Started Building Windows Services with Topshelf

My newest Pluralsight course “Getting Started Building Windows Services with Topshelf” has just been released.

Topshelf is an open source library that makes it easier to develop, test, and install Windows Services.

If you’re new to Windows Services, the course starts by introducing how Windows Services work and some of their features such as automatic service recovery and the ability to run in the background as different users.

The course then goes on to cover how to create a Windows Service with Topshelf as well as additional techniques such as debugging, logging, pause and continue and the ability to send custom commands to running services.

Check out the course link or browse all my Pluralsight courses.

Testing That Your Public APIs Have Not Changed Unexpectedly with PublicApiGenerator and Approval Tests

We can write automated tests to cover various aspects of the code we write. We can write unit/integration tests that test that the code is producing the expected outcomes. We can use ConventionTests to ensure internal code quality, for example that classes following a specified naming convention and exists in the correct namespace. We may even add the ability to create a business readable tests using tools such as SpecFlow or BDDfy.

Another aspect that we might want to ensure doesn’t change unexpectedly is the public API that our code exposes to callers.

Using PublicApiGenerator to Generate a Report of our Public API

The first step of ensuring our public API hasn’t changed is to be able to capture the public API in a readable way. The PublicApiGenerator NuGet package (from Jake Ginnivan) gives us this ability.

Suppose we have the following class defined:

public class Calculator
{
    public Calculator()
    {
        CurrentValue = 0;
    }

    public int CurrentValue { get; private set; }

    public void Clear()
    {
        CurrentValue = 0;
    }

    public void Add(int number)
    {
        CurrentValue += number;
    }
}

Notice here that this code defines the public API that consumers of the Calculator class can use. It’s this public API that we want to test to ensure it doesn’t change unexpectedly.

We might start with some unit tests as shown in the following code:

public class CalculatorTests
{
    [Fact]
    public void ShouldHaveInitialValue()
    {
        var sut = new Calculator();

        Assert.Equal(0, sut.CurrentValue);
    }

    [Fact]
    public void ShouldAdd()
    {
        var sut = new Calculator();

        sut.Add(1);

        Assert.Equal(1, sut.CurrentValue);
    }
}

These tests help us ensure the code is doing the right thing but do not offer any protection against the public API changing. We can now add a new test that uses PublicApiGenerator to generate a string “report” detailing the public members of our API. The following test code shows this in use:

[Fact]
public void ShouldHaveCorrectPublicApi()
{
    var sut = new Calculator();

    // Get the assembly that we want to generate the public API report for
    Assembly calculatorAssembly = sut.GetType().Assembly;

    // Use PublicApiGenerator to generate the API report
    string apiString = PublicApiGenerator.PublicApiGenerator.GetPublicApi(calculatorAssembly);

    // TODO: assert API has not changed
}

If we debug this test and look at the content of the apiString variable we’d see the following text:

[assembly: System.Runtime.InteropServices.ComVisibleAttribute(false)]
[assembly: System.Runtime.InteropServices.GuidAttribute("c2dc3732-a4a5-4baa-b4df-90f40aad1c6a")]
[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5.1", FrameworkDisplayName=".NET Framework 4.5.1")]

namespace Demo
{
    
    public class Calculator
    {
        public Calculator() { }
        public int CurrentValue { get; }
        public void Add(int number) { }
        public void Clear() { }
    }
}

Using Approval Tests to Assert the API Is Correct

Now in our test we have a string that represents the public API. We can combine PublicApiGenerator with the Approval Tests library to check that this API text doesn’t change.

First off we go and install the Approval Tests NuGet Package. We can then modify the test as shown below:

public class CalculatorApiTests
{
    [Fact]
    public void ShouldHaveCorrectPublicApi()
    {
        var sut = new Calculator();

        // Get the assembly that we want to generate the public API report for
        Assembly calculatorAssembly = sut.GetType().Assembly;

        // Use PublicApiGenerator to generate the API report
        string apiString = PublicApiGenerator.PublicApiGenerator.GetPublicApi(calculatorAssembly);

        // Use Approval Tests to verify the API hasn't changed
        Approvals.Verify(apiString);
    }
}

The first time we run this it will fail with a message such as “Failed Approval: Approval File "c:\…\Demo.Tests\CalculatorApiTests.ShouldHaveCorrectPublicApi.approved.txt" Not Found”. It will also generate a file called CalculatorApiTests.ShouldHaveCorrectPublicApi.received.txt. We can rename this to CalculatorApiTests.ShouldHaveCorrectPublicApi.approved.txt, run the test again and it will pass.

If we now modify the public API by changing a method signature (e.g. to public void Clear(int someParam)) and run the test again it will fail with a message such as “Received file c:\...\Demo.Tests\CalculatorApiTests.ShouldHaveCorrectPublicApi.received.txt does not match approved file c:\...\Demo.Tests\CalculatorApiTests.ShouldHaveCorrectPublicApi.approved.txt”.

Modifying the test and adding an Approval Tests reporter attribute ([UseReporter(typeof(DiffReporter))]) and running the test will now gives us a visual diff identifying the changes to the public API as shown in the following screenshot.

Approval Tests Diff Screenshot

To learn more about the features of Approval Tests, check out my Approval Tests for .NET Pluralsight course.

Testing Akka.NET Actor Systems

My new Pluralsight course Akka.NET Testing Fundamentals is now available.

Testing actor system brings a number of additional considerations over and above the concepts of traditional object oriented unit/integration testing.

While some additional testing support is required, for example as provided by Akka.NET’s TestKit, concepts such as “unit” and “integration” do translate to the testing of actors. For example a “unit” test becomes a test of the behaviour of a single actor in isolation and an “integration” test may involve multiple actors being testing together.

Just as with traditional OO testing where object dependencies can be mocked, so to with actor tests. For example, TestKit provides a number of pre-built mock actors that can be used if the actor(s) being tested need to be isolated. The simplest of these pre-built mock actors is the BlackHoleActor that will simply and silently accept any message sent to it and “swallow” the message. The EchoActor is another pre-built mock actor that will echo any message sent to it back into the test actor system instance as well as optionally back to the sending actor. The TestProbe pre-built mock actor is a more generalised mock actor and can be used in a number of useful ways.

To get access to the benefits of the actor testing infrastructure, the test class inherits from the TestKit base class. By doing this we get access to an automatically created actor system instance into which we can instantiate the actor(s) that need testing.

When testing an actor, it can be treated as a black or white box. A black box test would involve sending a message to the actor and examining (and asserting on) response message(s). Utilising TestKit we can also write white box actor tests where we can get access to the “internal” actor state directly and make asserts on this internal state.

If you’re new to the Actor Model or Akka.NET, check out the docs or my introductory Pluralsight course: Building Concurrent Applications with the Actor Model in Akka.NET.