Skip to content

Instantly share code, notes, and snippets.

@dhilst
Last active November 21, 2020 13:13
Show Gist options
  • Save dhilst/54770ee833806c330cde849fcbb3e82c to your computer and use it in GitHub Desktop.
Save dhilst/54770ee833806c330cde849fcbb3e82c to your computer and use it in GitHub Desktop.
Typed primitives in c#
using System;
namespace hello
{
// A typed primitive it narrows the type of primitive
class TypedPrim<T>
{
public T Value { get; set; }
public static implicit operator T(TypedPrim<T> v) => v.Value;
public static explicit operator TypedPrim<T>(T v) => new TypedPrim<T>() { Value = v };
}
class DebtorId : TypedPrim<int> { }
class Name : TypedPrim<string> { }
class Address : TypedPrim<string> { }
class Program
{
// Function receiving int
static int Inc(int a) => a + 1;
// Function receiving typed stuff
static void UpdateDebtor(DebtorId a, Name n, Address addr) { }
static void Main(string[] args)
{
int i = 1;
DebtorId id = new DebtorId() { Value = i };
// You have to explicty cast from primitive to TypedPrim
var address = (Address)"My street";
var name = (Name)"Daniel";
// Every function accepting primitive type will just work
Inc(id);
// It catches up if you swap the parameters
// something that a an Function<int, string, string, ...> wouldn't catch
// UpdateDebtor(id, address, name); // => Argument 2: cannot convert from 'hello.Address' to 'hello.Name'
// And the expected call typechecks
UpdateDebtor(id, name, address);
Console.WriteLine("Hello World!");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment