Skip to content

Instantly share code, notes, and snippets.

@cstanfill
Created November 18, 2014 23:09
Show Gist options
  • Save cstanfill/622423f92e2f95ae39bc to your computer and use it in GitHub Desktop.
Save cstanfill/622423f92e2f95ae39bc to your computer and use it in GitHub Desktop.
Typesafe bivariant arrays in C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BivariantArrays
{
public interface IReadable<in T>
{
public T this[int i] { get; }
}
public interface IWriteable<out T>
{
public T this[int i] { set; }
}
public interface IReadWrite<T> : IReadable<T>, IWriteable<T>
{
}
public class EString
{
protected string contents;
public EString(string contents) {
this.contents = contents;
}
public char this[int i] {
get {
return contents[i];
}
}
}
public class LengthString : EString
{
public LengthString(string contents) : base(contents) { }
public int Length {
get {
return contents.Length;
}
}
}
public class PadString : EString
{
private char pad;
public PadString(string contents, char pad) : base(contents) {
this.pad = pad;
}
public override PadString(string contents) : this(contents, ' ') {
}
public override char this[int i]
{
get {
if (i < 0 || i >= contents.Length) {
return pad;
} else {
return contents[i];
}
}
}
}
public class BivariantArray<T> : IReadWrite<T>
{
private T[] contents;
public BivariantArray(int capacity) {
contents = new T[capacity];
}
public T this[int i]
{
get {
return contents[i];
}
set {
contents[i] = value;
}
}
public static void Main() {
BivariantArray<EString> estrings = new BivariantArray<EString>(1);
BivariantArray<PadString> pstrings = new BivariantArray<PadString>(1);
BivariantArray<LengthString> lstrings = new BivariantArray<LengthString>(1);
pstrings[0] = new PadString("dog");
lstrings[0] = new LengthString("cat");
estrings[0] = new EString("mammal");
estrings[0] = new PadString("wolf");
/* XXX pstrings[0] = new EString("quadruped"); Fails typecheck */
/* XXX pstrings[0] = new LengthString("tiger"); Fails typecheck */
EString dog2 = pstrings[0];
/* XXX PadString mammal2 = estrings[0]; Fails typecheck */
/* XXX LengthString dog3 = pstrings[0]; Fails typecheck */
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment