Created
July 16, 2014 13:24
-
-
Save bradphelan/26c0e84197092620359a to your computer and use it in GitHub Desktop.
Type system abuse to simulate dependent types in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IDigit { | |
int Value { get; } | |
} | |
public class _0 : IDigit { public int Value { get { return 0;} } } | |
public class _1 : IDigit { public int Value { get { return 1;} } } | |
public class _2 : IDigit { public int Value { get { return 2;} } } | |
public class _3 : IDigit { public int Value { get { return 3;} } } | |
public interface ILength { | |
int Value { get; } | |
} | |
public class Length<T0> : ILength | |
where T0 : IDigit, new() | |
{ | |
public int Value | |
{ | |
get | |
{ | |
return new T0().Value; | |
} | |
} | |
} | |
public class Length<T1,T0> : ILength where T0 : IDigit, new() where T1 : IDigit, new() | |
{ | |
public int Value | |
{ | |
get | |
{ | |
return new T1().Value*10 + new T0().Value; | |
} | |
} | |
} | |
public class Length<T2, T1, T0> : ILength | |
where T0 : IDigit, new() | |
where T1 : IDigit, new() | |
where T2 : IDigit, new() | |
{ | |
public int Value | |
{ | |
get | |
{ | |
return new T2().Value*100 + new T1().Value*10 + new T0().Value; | |
} | |
} | |
} | |
public class String<TLength> where TLength : ILength, new() { | |
public int _MaxLength; | |
public String(){ | |
_MaxLength = new TLength().Value; | |
} | |
} | |
public void LengthCheck(String<Length<_3, _1, _2>> s312) | |
{ | |
Console.WriteLine(s312._MaxLength); | |
} | |
[Fact] | |
public void FactMethodName() | |
{ | |
var s312 = new String<Length<_3, _1, _2>>(); | |
var s313 = new String<Length<_3, _1, _3>>(); | |
// Passes | |
s312._MaxLength.Should().Be(312); | |
// Type checks | |
LengthCheck(s312); | |
// Fails to type check | |
LengthCheck(s313); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment