Skip to content

Instantly share code, notes, and snippets.

@doubleday
Last active August 29, 2015 14:01
Show Gist options
  • Save doubleday/2161552402bfe44c428a to your computer and use it in GitHub Desktop.
Save doubleday/2161552402bfe44c428a to your computer and use it in GitHub Desktop.
using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
namespace Scratch
{
public class Program
{
public static void Main(string[] pArgs)
{
var context = new Context();
context.AddAttribute(Attributes.GreetingAttribute, "Hello, World!");
Debug.Assert(context.AttributesOfType(Attributes.GreetingAttribute).First().Value == "Hello, World!");
// type inference doesnt work here
context.AddAttribute(Attributes.BoxedHasExtraMove, (ValueBox<bool>) true);
Debug.Assert(context.AttributesOfType(Attributes.BoxedHasExtraMove).First().Value);
// this fails because there's no value type covariance :-(
context.AddAttribute(Attributes.HasExtraMove, true);
Debug.Assert(context.AttributesOfType(Attributes.HasExtraMove).First().Value);
}
}
// Do I really need this ???
public class ValueBox<ValueType> where ValueType : struct
{
readonly ValueType _value;
public ValueType Value { get { return _value; } }
public ValueBox(ValueType pValue)
{
_value = pValue;
}
public static implicit operator ValueType(ValueBox<ValueType> pPrimitive)
{
return pPrimitive.Value;
}
public static implicit operator ValueBox<ValueType>(ValueType pValue)
{
return new ValueBox<ValueType>(pValue);
}
}
public interface IAttributeSpec<out ValueType> {}
public static class Attributes
{
class AttributeSpec<ValueType> : IAttributeSpec<ValueType> {}
public static readonly IAttributeSpec<string> GreetingAttribute = new AttributeSpec<string>();
public static readonly IAttributeSpec<ValueBox<bool>> BoxedHasExtraMove = new AttributeSpec<ValueBox<bool>>();
public static readonly IAttributeSpec<bool> HasExtraMove = new AttributeSpec<bool>();
}
public interface IAttribute<out ValueType>
{
IAttributeSpec<ValueType> Type { get; }
ValueType Value { get; }
}
public class Context
{
class Attribute<ValueType> : IAttribute<ValueType>
{
readonly IAttributeSpec<ValueType> _type;
public IAttributeSpec<ValueType> Type { get { return _type; } }
readonly ValueType _value;
public ValueType Value { get { return _value; } }
public Attribute(IAttributeSpec<ValueType> pType, ValueType pValue)
{
_type = pType;
_value = pValue;
}
}
List<IAttribute<object>> _attributes = new List<IAttribute<object>>();
public void AddAttribute<ValueType>(IAttributeSpec<ValueType> pType, ValueType pValue)
{
// doesnt work for value types
_attributes.Add((IAttribute<object>) new Attribute<ValueType> (pType, pValue));
}
public IEnumerable<IAttribute<ValueType>> AttributesOfType<ValueType>(IAttributeSpec<ValueType> pType)
{
return _attributes.OfType<IAttribute<ValueType>>().Where(attr => attr.Type == pType);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment