using System;
namespace Roblox
{
///
/// Guarantees a non-null instance of type T
///
/// http://docs.google.com/a/roblox.com/Doc?docid=0ATG2rw7nIIsFZGY4ZHcy725MTBnZG5qcDdmbQ&hl=en
///
///
public struct NonNullable where T : class
{
private readonly T _t;
internal NonNullable(T t)
{
_t = t;
}
public T Value
{
get
{
if (_t == null)
throw new NullReferenceException("Uninitialized NonNullable of type " + typeof(T).Name);
return _t;
}
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
///
/// Returns the text representation of the value of the current System.Nullable object.
///
public override string ToString()
{
return Value.ToString();
}
public static implicit operator T(NonNullable n)
{
return n.Value;
}
public override bool Equals(object other)
{
// http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx
if (other == null)
return false;
return _t == other;
}
public bool Equals(T other)
{
// http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx
if (other == null)
return false;
return this._t == other;
}
public bool Equals(NonNullable other)
{
// http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx
// Strictly speaking, _t should never be null,
// but we are not allowed to throw in an equal call.
// Instead, we follow the rule to return false if the
// value compared against is null
if (other._t == null)
return false;
return this._t == other._t;
}
public static bool operator ==(NonNullable a, NonNullable b)
{
return a._t == b._t;
}
public static bool operator !=(NonNullable a, NonNullable b)
{
return a._t != b._t;
}
public static NonNullable ToNonNull(T t)
{
if (t == null)
throw new NullReferenceException("Incorrect usage of NonNullable of type " + typeof(T).Name + ". Caller must check for null before calling ToNonNull.");
return new NonNullable(t);
}
}
public static class NonNullExtensions
{
///
/// Safely and efficiently promotes NonNullable types to base classes
///
public static NonNullable Convert(this NonNullable t)
where T : class, TBase
where TBase : class
{
return new NonNullable(t.Value);
}
}
}