Merge remote-tracking branch 'origin/6.2.0-membershipprovider' into 7.0.0
Conflicts: src/Umbraco.Tests/ObjectExtensionsTests.cs src/Umbraco.Web/WebBootManager.cs
This commit is contained in:
@@ -16,7 +16,6 @@ namespace Umbraco.Core
|
||||
{
|
||||
public static class ObjectExtensions
|
||||
{
|
||||
|
||||
//private static readonly ConcurrentDictionary<Type, Func<object>> ObjectFactoryCache = new ConcurrentDictionary<Type, Func<object>>();
|
||||
|
||||
public static IEnumerable<T> AsEnumerableOfOne<T>(this T input)
|
||||
@@ -93,8 +92,30 @@ namespace Umbraco.Core
|
||||
//check for string so that overloaders of ToString() can take advantage of the conversion.
|
||||
if (destinationType == typeof(string)) return Attempt<object>.Succeed(input.ToString());
|
||||
|
||||
if (!destinationType.IsGenericType || destinationType.GetGenericTypeDefinition() != typeof(Nullable<>))
|
||||
// if we've got a nullable of something, we try to convert directly to that thing.
|
||||
if (destinationType.IsGenericType && destinationType.GetGenericTypeDefinition() == typeof(Nullable<>))
|
||||
{
|
||||
// recursively call into myself with the inner (not-nullable) type and handle the outcome
|
||||
var nonNullable = input.TryConvertTo(Nullable.GetUnderlyingType(destinationType));
|
||||
|
||||
// and if sucessful, fall on through to rewrap in a nullable; if failed, pass on the exception
|
||||
if (nonNullable.Success)
|
||||
input = nonNullable.Result; // now fall on through...
|
||||
else
|
||||
return Attempt<object>.Fail(nonNullable.Exception);
|
||||
}
|
||||
|
||||
// we've already dealed with nullables, so any other generic types need to fall through
|
||||
if (!destinationType.IsGenericType)
|
||||
{
|
||||
if (input is string)
|
||||
{
|
||||
var result = TryConvertToFromString(input as string, destinationType);
|
||||
|
||||
// if we processed the string (succeed or fail), we're done
|
||||
if (result.HasValue) return result.Value;
|
||||
}
|
||||
|
||||
//TODO: Do a check for destination type being IEnumerable<T> and source type implementing IEnumerable<T> with
|
||||
// the same 'T', then we'd have to find the extension method for the type AsEnumerable() and execute it.
|
||||
|
||||
@@ -158,7 +179,6 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (TypeHelper.IsTypeAssignableFrom<IConvertible>(input))
|
||||
{
|
||||
try
|
||||
@@ -175,6 +195,119 @@ namespace Umbraco.Core
|
||||
return Attempt<object>.Fail();
|
||||
}
|
||||
|
||||
private static Nullable<Attempt<object>> TryConvertToFromString(this string input, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string))
|
||||
return Attempt<object>.Succeed(input);
|
||||
|
||||
if (input == null || input.Length == 0)
|
||||
{
|
||||
if (destinationType == typeof(Boolean))
|
||||
return Attempt<object>.Succeed(false); // special case for booleans, null/empty == false
|
||||
else if (destinationType == typeof(DateTime))
|
||||
return Attempt<object>.Succeed(DateTime.MinValue);
|
||||
}
|
||||
|
||||
// we have a non-empty string, look for type conversions in the expected order of frequency of use...
|
||||
if (destinationType.IsPrimitive)
|
||||
{
|
||||
if (destinationType == typeof(Int32))
|
||||
{
|
||||
Int32 value;
|
||||
return Int32.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Int64))
|
||||
{
|
||||
Int64 value;
|
||||
return Int64.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Boolean))
|
||||
{
|
||||
Boolean value;
|
||||
if (Boolean.TryParse(input, out value))
|
||||
return Attempt<object>.Succeed(value); // don't declare failure so the CustomBooleanTypeConverter can try
|
||||
}
|
||||
else if (destinationType == typeof(Int16))
|
||||
{
|
||||
Int16 value;
|
||||
return Int16.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Double))
|
||||
{
|
||||
Double value;
|
||||
return Double.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Single))
|
||||
{
|
||||
Single value;
|
||||
return Single.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Char))
|
||||
{
|
||||
Char value;
|
||||
return Char.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Byte))
|
||||
{
|
||||
Byte value;
|
||||
return Byte.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(SByte))
|
||||
{
|
||||
SByte value;
|
||||
return SByte.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(UInt32))
|
||||
{
|
||||
UInt32 value;
|
||||
return UInt32.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(UInt16))
|
||||
{
|
||||
UInt16 value;
|
||||
return UInt16.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(UInt64))
|
||||
{
|
||||
UInt64 value;
|
||||
return UInt64.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
}
|
||||
else if (destinationType == typeof(Guid))
|
||||
{
|
||||
Guid value;
|
||||
return Guid.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(DateTime))
|
||||
{
|
||||
DateTime value;
|
||||
return DateTime.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(DateTimeOffset))
|
||||
{
|
||||
DateTimeOffset value;
|
||||
return DateTimeOffset.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(TimeSpan))
|
||||
{
|
||||
TimeSpan value;
|
||||
return TimeSpan.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Decimal))
|
||||
{
|
||||
Decimal value;
|
||||
return Decimal.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Version))
|
||||
{
|
||||
Version value;
|
||||
return Version.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
// E_NOTIMPL IPAddress, BigInteger
|
||||
|
||||
return null; // we can't decide...
|
||||
}
|
||||
|
||||
internal static void CheckThrowObjectDisposed(this IDisposable disposable, bool isDisposed, string objectname)
|
||||
{
|
||||
//TODO: Localise this exception
|
||||
@@ -296,7 +429,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
return "\"{0}\"".InvariantFormat(obj);
|
||||
}
|
||||
if (obj is int || obj is Int16 || obj is Int64 || obj is double || obj is bool || obj is int? || obj is Int16? || obj is Int64? || obj is double? || obj is bool?)
|
||||
if (obj is int || obj is Int16 || obj is Int64 || obj is float || obj is double || obj is bool || obj is int? || obj is Int16? || obj is Int64? || obj is float? || obj is double? || obj is bool?)
|
||||
{
|
||||
return "{0}".InvariantFormat(obj);
|
||||
}
|
||||
@@ -435,6 +568,5 @@ namespace Umbraco.Core
|
||||
return "[GetPropertyValueException]";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user