NetFabric.Angle: type-safety and units-safety for angles

NetFabric.Angle: type-safety and units-safety for angles

Why would I need an Angle structure?

Angles are usually represented as a floating-point. Its value is usually in radians but some frameworks use degrees, or even both. Unity, for example, uses radians in Mathf but degrees in Transform. The only way to find this is by reading the documentation. There’s nothing explicit in the method declaration and the compiler cannot make any validation.

There is also nothing in Mathf, or in System.Math, that tells the developer or the compiler that Sin() takes an angle value and returns a floating-point value, while Asin() is the other way around.

NetFabric.Angle implements a .NET structure that represents an angle, giving you efficient type-safety and units-safety.


When using the Angle structure it’s possible to impose rules like “an angle can only be added to another angle”.

Looking at the method Asin below, you can immediately see that it returns an Angle. The compiler will throw an error when you try to assign it to anything else.

double Sin (Angle angle);
Angle Asin(double value);

You also don’t have to worry about what units were used to create the angle, simplifying code and documentation.


To create an Angle you have to explicitly specify the units you are using:

var right0 = Angle.FromRadian(Math.PI / 2.0);
var right1 = Angle.FromDegrees(90.0);
var right2 = Angle.FromGradian(100.0);

Same when you want to get the value:

var radians = angle.ToRadians();
var degrees = angle.ToDegrees();
var gradians = angle.ToGradians();

When using math operations, comparison, trigonometry, linear interpolation and so on, you don’t have to worry about units.


Angles are used on any platform. From micro-controllers to data centers, passing by mobile devices and gaming consoles. NetFabric.Angle is available for as many .NET flavors as possible. It’s available as a Nuget package and as a .unitypackage.

The source project structure to achieve this is described on my previous post.

IDE integration

NetFabric.Angle comes with debugger visualization metadata that is recognized by Visual Studio. When stopped at a breakpoint and the mouse cursor hovering on an Angle variable, the DataTip shows the variable value in degrees and when expanded shows the value in all angle measurement units. This makes it easier to understand the value of the variable.


The Unity package includes extension methods for Unity classes like Quaternion, Transform, Vector2 and Vector3, allowing the direct use o Angle.

public class NewBehaviourScript : MonoBehaviour {

    [AngleDegreesRange(-180.0, 180.0)]
    public Angle RotateX;

    void Update () {
        transform.Rotate(Time.deltaTime * RotateX, Angle.Zero, Angle.Zero);


The Unity package also contains a custom property drawer for Angle. For now, it contains the same slider and text box with the value in degrees as the existing floating-point angles but you gain type-safety and units-safety in the scripts. This custom drawer also takes into account the angle range metadata attribute that can be specified in any of the angle measurement units.


Featured image: “Angles” by Benjamin Horn


A true cross-platform .NET library (part 1)

A true cross-platform .NET library (part 1)

.NET was designed to be cross-language and cross-platform. Unfortunately along its history, Microsoft decided to fork it into subsets, starting with Silverlight and Windows Phone 8. The CLR also changed from .NET 3.5 to .NET 4.0. A single assembly solution no longer works for all .NET flavors.

I recently released a small open-source library and wanted to make it available on as many .NET flavors as possible, including Xamarin, Unity and .NET Micro Framework.

NOTE: .NET Platform Standard is an open-source effort by Microsoft to fix the subsets issue but Xamarin and Unity will take time to adopt the new framework. Still, I don’t believe it will ever consider .NET Micro Framework.

Portable Class Library

A PCL project generates an assembly that complies with multiple .NET flavors. Visual Studio has a dialog in the project settings where we can check the flavors we want to target.


As each flavor is a subset of .NET, the more flavors we add, the less features we may have available. My small project doesn’t have any specific dependency so it wasn’t an issue but it may be for more complex projects. If you run into problems, I suggest this other post by Daniel Plaisted.

To easily deploy into projects, we can package the assembly into a nuget package. To create one of these packages we need to specify in the .nuspec file the supported platforms in the form of folders. The name of the folder for a PCL assembly can be quite complex. For more info check this other post. For Xamarin NuGet support, I had to open one of their packages using NuGet Package Explorer and check what folder structure they use.

We should be done by now. Unfortunately that’s not really true…


Unity‘s script engine is built on top of CLR 2.0, meaning it supports .NET up to version 3.5. As you can see from the next image, PCL only supports .NET 4 and up. There is no PCL support for Unity. 😦


To target Unity, we need to add a new ‘class library’ project to the solution. Use a ‘.Net35’ sufix on the name to make it easier to find. In the project settings, set the ‘target framework’ to ‘.NET Framework 3.5 Client Profile’. The assembly name doesn’t need to have the platform sufix as it will not conflict with others later. NuGet will only install the assembly specific to the project traget platform.

NOTE: If you have code that depends on UnityEngine.dll or UnityEditor.dll, my suggestion is to add a ‘class library’ for each, with ‘.Unity’ or ‘.UnityEditor’ sufixes, that also targets ‘.NET Framework 3.5 Client Profile’. Don’t forget to place the ‘.UnityEditor’ assembly in a ‘Editor’ folder so that it’s not shipped with the application runtime.

We now need to share the source code between the PCL and .NET 3.5 projects. The best way to do this is to add a new ‘shared project’ to the solution. Use ‘.Shared’ at the end of the project name to make it also easier to find. Move the .cs source files into this project. This new project can then be added as a reference in the other projects and its content is compiled as if it was inside these other projects.


The resulting assembly can be added to the previous NuGet package but into the ‘lib/net35’ folder.

Unfortunately Unity does not support NuGet. It uses its own Asset Package format. To create one of these packages, we need to open Unity,  add the assembly to the Unity project’s ‘Assets’ folder and then click on ‘Export Package…’ under the ‘Assets’ menu item. We can distribute this package as is and/or make it available at the Unity Asset Store.

.NET Micro Framework

On my free time I like to play with micro-controllers. I’ve been using boards like the Netduino and the FEZ Cerbuino Bee. They support .NET Micro Framework and I like to use my .NET libraries in these projects too.

To develop for this platform we need to install the framework and the Visual Studio extension available at

.NET Micro Framework SDK 4.3 and older are available at under ‘SDK MSI’. You don’t need to install the Visual Studio extensions from here if you are already using the extension for Visual Studio 2015.

If you use AppVeyor for continuous integration, you can use these PowerShell scripts to add support for .NET Micro Framework builds.

We now need to add a new ‘Class Library’ project from the ‘Micro Framework’ category.


We can set the target framework version in the project settings once it’s created. This means we need one project for each targeted version. Name the projects with sufixes like ‘.NetMF42’, ‘.NetMF43’ and ‘.NetMF44’ so that the version is easy to spot.


The .cs source code has to added to these new projects. Unfortunately .NET MF projects do not support shared projects.


We’ll have to use the old-fashioned solution by adding the source files as links. It’s available in the ‘Add Existing Item…’ dialog as a drop-down of the ‘Add’ button.


The resulting assemblies can then be added to the previous NuGet package into the ‘lib/netmf43’, ‘lib/netmf43’ and ‘lib/netmf44’ folders respectively. Note that the  folders ‘be’ and ‘le’ and the assemblies in them also have to be added to the package.


If you want to really support multiple .NET flavors, a PCL or a shared project may not be the ‘one size fits all’ solution but with some work you can create a single NuGet package that targets most .NET flavors. Some call this the “bait and switch PCL trick“.

Clone NetFabric.Angle for a sample of the project structure described in this post.

Now, go to part 2 on how to manage platform-specif code.