in Arriba/Arriba/Structures/Value.cs [481:674]
public bool TryConvert(Type t, out object result)
{
// Null never converts
if (_value == null)
{
result = null;
return false;
}
// If original value already right, return as-is
if (_value.GetType().Equals(t))
{
result = _value;
return true;
}
// Directly convert to string if requested without determination
if (t == typeof(string))
{
if (_value is DateTime)
{
result = ((DateTime)_value).ToString("u", CultureInfo.InvariantCulture);
return true;
}
else if (_value is ValueTypeReference<DateTime>)
{
result = (_value as ValueTypeReference<DateTime>).Value.ToString("u", CultureInfo.InvariantCulture);
return true;
}
else
{
result = _value.ToString();
return true;
}
}
// Directly convert to ByteBlock if requested without determination
if (t == typeof(ByteBlock))
{
result = ToByteBlock();
return true;
}
// If this is currently a ByteBlock and we didn't want that, retry conversion as a string
if (_value is ByteBlock)
{
_value = _value.ToString();
}
// Otherwise, use type determination to detect
object idealTypeValue = DetermineIdealTypeValue();
// If the ideal type was requested, return as determined
if (idealTypeValue.GetType().Equals(t))
{
result = idealTypeValue;
return true;
}
// If boolean and another type requested, offer as a number
if (idealTypeValue is bool)
{
idealTypeValue = ((bool)idealTypeValue) ? 1 : 0;
}
// Upconvert numbers and downconvert if within range
if (idealTypeValue is double)
{
double asDouble = (double)idealTypeValue;
if (t == typeof(float))
{
if (asDouble >= float.MinValue && asDouble <= float.MaxValue)
{
result = (float)asDouble;
return true;
}
}
}
else if (idealTypeValue is ulong)
{
ulong asULong = (ulong)idealTypeValue;
if (t == typeof(float))
{
result = (float)asULong;
return true;
}
else if (t == typeof(double))
{
result = (double)asULong;
return true;
}
}
else if (idealTypeValue is long)
{
long asLong = (long)idealTypeValue;
if (t == typeof(ulong))
{
if (asLong >= 0)
{
result = (ulong)asLong;
return true;
}
}
else if (t == typeof(uint))
{
if (asLong >= uint.MinValue && asLong <= uint.MaxValue)
{
result = (uint)asLong;
return true;
}
}
else if (t == typeof(int))
{
if (asLong >= int.MinValue && asLong <= int.MaxValue)
{
result = (int)asLong;
return true;
}
}
else if (t == typeof(ushort))
{
if (asLong >= ushort.MinValue && asLong <= ushort.MaxValue)
{
result = (ushort)asLong;
return true;
}
}
else if (t == typeof(short))
{
if (asLong >= short.MinValue && asLong <= short.MaxValue)
{
result = (short)asLong;
return true;
}
}
else if (t == typeof(sbyte))
{
if (asLong >= sbyte.MinValue && asLong <= sbyte.MaxValue)
{
result = (sbyte)asLong;
return true;
}
}
else if (t == typeof(byte))
{
if (asLong >= byte.MinValue && asLong <= byte.MaxValue)
{
result = (byte)asLong;
return true;
}
}
else if (t == typeof(float))
{
result = (float)asLong;
return true;
}
else if (t == typeof(double))
{
result = (double)asLong;
return true;
}
else if (t == typeof(bool))
{
if (asLong == 0)
{
result = false;
return true;
}
else if (asLong == 1)
{
result = true;
return true;
}
}
}
// Consider non-preferred string parse options
if (_value is string)
{
if (t == typeof(TimeSpan))
{
TimeSpan asTimeSpan;
bool isTimeSpan = TimeSpan.TryParse((string)_value, out asTimeSpan);
result = asTimeSpan;
return isTimeSpan;
}
}
// Otherwise, report not convertible
result = null;
return false;
}