ConstrainedNumber.cs
Code: Select all
using System;
namespace Editor
{
/// <summary>
/// Based on Triynko's reply to http://stackoverflow.com/questions/577946/can-i-avoid-casting-an-enum-value-when-i-try-to-use-or-return-it
/// </summary>
/// <typeparam name="T">Type</typeparam>
public class ConstrainedNumber<T>
{
/// <summary>
/// The actual number
/// </summary>
public readonly T data;
/// <summary>
/// Constraint for this constrained number
/// </summary>
/// <typeparam name="U">Type (should probably be the same as T)</typeparam>
/// <param name="constrainer">Constraint definition</param>
/// <returns>True if constraint is met, false otherwise</returns>
protected delegate bool NumberConstraint<U>(U constrainer);
/// <summary>
/// Constructor
/// </summary>
/// <param name="value"></param>
/// <param name="constraint"></param>
protected ConstrainedNumber(T value, NumberConstraint<T> constraint)
{
if (!constraint(value))
throw new ArgumentException("Value does not meet constraint.");
data = value;
}
/// <summary>
/// Copy constructor
/// </summary>
/// <param name="value"></param>
protected ConstrainedNumber(T value)
{
data = value;
}
/// <summary>
/// Convert from ConstrainedNumber to its T-type
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public static implicit operator T(ConstrainedNumber<T> i)
{
return i.data;
}
/// <summary>
/// Define equality
/// </summary>
/// <param name="obj">Object to compare to</param>
/// <returns>True on data equal, false otherwise</returns>
public override bool Equals(object obj)
{
ConstrainedNumber<T> test = obj as ConstrainedNumber<T>;
if (test != null)
{
if (this.data.Equals(test.data))
return true;
}
return false;
}
/// <summary>
/// Required to define Equals()
/// </summary>
/// <returns>No idea</returns>
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
Code: Select all
/// <summary>
/// Using a class instead of an enumerator to limit range and avoid casts everywhere.
/// </summary>
public class SheetTypes : ConstrainedNumber<int>
{
private static readonly NumberConstraint<int> constraint = (int x) => (x >= 0) && (x <= 2);
public static readonly SheetTypes TILE = new SheetTypes(0);
public static readonly SheetTypes OBJECT = new SheetTypes(1);
public static readonly SheetTypes NUM_SHEET_TYPES = new SheetTypes(2);
private SheetTypes(int value) : base(value, constraint) { }
private SheetTypes(SheetTypes original) : base(original) { }
public static implicit operator SheetTypes(int value)
{
switch (value)
{
case 0: return TILE;
case 1: return OBJECT;
case 2: return NUM_SHEET_TYPES;
}
throw new ArgumentException("Value " + value.ToString() + " out of range.");
}
}