2012-07-31 00:02:27 +06:00
using System ;
using System.Collections ;
using System.Collections.Concurrent ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.IO ;
using System.Linq ;
using System.Linq.Expressions ;
using System.Reflection ;
using System.Runtime.Serialization ;
using System.Runtime.Serialization.Formatters.Binary ;
using System.Security ;
using System.Xml ;
namespace Umbraco.Core
{
2013-04-30 16:43:59 -10:00
public static class ObjectExtensions
2012-07-31 00:02:27 +06:00
{
//private static readonly ConcurrentDictionary<Type, Func<object>> ObjectFactoryCache = new ConcurrentDictionary<Type, Func<object>>();
public static IEnumerable < T > AsEnumerableOfOne < T > ( this T input )
{
return Enumerable . Repeat ( input , 1 ) ;
}
public static void DisposeIfDisposable ( this object input )
{
var disposable = input as IDisposable ;
if ( disposable ! = null ) disposable . Dispose ( ) ;
}
/// <summary>
/// Provides a shortcut way of safely casting an input when you cannot guarantee the <typeparam name="T"></typeparam> is an instance type (i.e., when the C# AS keyword is not applicable)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="input">The input.</param>
/// <returns></returns>
2013-04-30 16:43:59 -10:00
internal static T SafeCast < T > ( this object input )
2012-07-31 00:02:27 +06:00
{
if ( ReferenceEquals ( null , input ) | | ReferenceEquals ( default ( T ) , input ) ) return default ( T ) ;
if ( input is T ) return ( T ) input ;
return default ( T ) ;
}
/// <summary>
/// Tries to convert the input object to the output type using TypeConverters
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="input"></param>
/// <returns></returns>
public static Attempt < T > TryConvertTo < T > ( this object input )
{
var result = TryConvertTo ( input , typeof ( T ) ) ;
2013-03-12 22:58:21 +04:00
if ( ! result . Success )
{
//just try a straight up conversion
try
{
var converted = ( T ) input ;
2013-09-11 08:22:28 +02:00
return Attempt < T > . Succeed ( converted ) ;
2013-03-12 22:58:21 +04:00
}
catch ( Exception e )
{
2013-09-04 17:14:06 +02:00
return Attempt < T > . Fail ( e ) ;
2013-03-12 22:58:21 +04:00
}
}
2013-09-11 08:22:28 +02:00
return ! result . Success ? Attempt < T > . Fail ( ) : Attempt < T > . Succeed ( ( T ) result . Result ) ;
2012-07-31 00:02:27 +06:00
}
/// <summary>
/// Tries to convert the input object to the output type using TypeConverters. If the destination type is a superclass of the input type,
/// if will use <see cref="Convert.ChangeType(object,System.Type)"/>.
/// </summary>
/// <param name="input">The input.</param>
/// <param name="destinationType">Type of the destination.</param>
/// <returns></returns>
public static Attempt < object > TryConvertTo ( this object input , Type destinationType )
{
2013-08-14 20:08:45 +10:00
//if it is null and it is nullable, then return success with null
if ( input = = null & & destinationType . IsGenericType & & destinationType . GetGenericTypeDefinition ( ) = = typeof ( Nullable < > ) )
{
2013-09-12 12:35:43 +02:00
return Attempt < object > . Succeed ( null ) ;
2013-08-14 20:08:45 +10:00
}
2013-10-29 18:46:12 +11:00
//if its not nullable and it is a value type
if ( input = = null & & destinationType . IsValueType ) return Attempt < object > . Fail ( ) ;
//if the type can be null, then no problem
if ( input = = null & & destinationType . IsValueType = = false ) return Attempt < object > . Succeed ( null ) ;
2012-07-31 00:02:27 +06:00
2013-09-11 08:22:28 +02:00
if ( destinationType = = typeof ( object ) ) return Attempt . Succeed ( input ) ;
2012-07-31 00:02:27 +06:00
2013-09-11 08:22:28 +02:00
if ( input . GetType ( ) = = destinationType ) return Attempt . Succeed ( input ) ;
2012-07-31 00:02:27 +06:00
2013-09-11 11:57:15 +10:00
//check for string so that overloaders of ToString() can take advantage of the conversion.
2013-09-11 11:06:14 +02:00
if ( destinationType = = typeof ( string ) ) return Attempt < object > . Succeed ( input . ToString ( ) ) ;
2012-07-31 00:02:27 +06:00
2013-10-17 19:12:08 -05:00
// if we've got a nullable of something, we try to convert directly to that thing.
if ( destinationType . IsGenericType & & destinationType . GetGenericTypeDefinition ( ) = = typeof ( Nullable < > ) )
2012-07-31 00:02:27 +06:00
{
2013-11-02 15:18:08 +11:00
var underlyingType = Nullable . GetUnderlyingType ( destinationType ) ;
//special case for empty strings for bools/dates which should return null if an empty string
var asString = input as string ;
if ( asString ! = null & & string . IsNullOrEmpty ( asString ) & & ( underlyingType = = typeof ( DateTime ) | | underlyingType = = typeof ( bool ) ) )
{
return Attempt < object > . Succeed ( null ) ;
}
2013-10-17 19:12:08 -05:00
// recursively call into myself with the inner (not-nullable) type and handle the outcome
2013-11-02 15:18:08 +11:00
var nonNullable = input . TryConvertTo ( underlyingType ) ;
2013-10-17 19:12:08 -05:00
// 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 ;
}
2013-03-12 22:58:21 +04:00
//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.
2012-07-31 00:02:27 +06:00
if ( TypeHelper . IsTypeAssignableFrom ( destinationType , input . GetType ( ) )
& & TypeHelper . IsTypeAssignableFrom < IConvertible > ( input ) )
{
2013-03-12 22:58:21 +04:00
try
{
var casted = Convert . ChangeType ( input , destinationType ) ;
2013-09-11 08:22:28 +02:00
return Attempt . Succeed ( casted ) ;
2013-03-12 22:58:21 +04:00
}
catch ( Exception e )
{
2013-09-04 17:14:06 +02:00
return Attempt < object > . Fail ( e ) ;
2013-03-12 22:58:21 +04:00
}
2012-07-31 00:02:27 +06:00
}
}
var inputConverter = TypeDescriptor . GetConverter ( input ) ;
2012-09-29 07:20:23 +07:00
if ( inputConverter . CanConvertTo ( destinationType ) )
2012-07-31 00:02:27 +06:00
{
2012-09-29 07:20:23 +07:00
try
2012-07-31 00:02:27 +06:00
{
2012-09-29 07:20:23 +07:00
var converted = inputConverter . ConvertTo ( input , destinationType ) ;
2013-09-11 08:22:28 +02:00
return Attempt . Succeed ( converted ) ;
2012-09-29 07:20:23 +07:00
}
catch ( Exception e )
{
2013-09-04 17:14:06 +02:00
return Attempt < object > . Fail ( e ) ;
2012-07-31 00:02:27 +06:00
}
}
if ( destinationType = = typeof ( bool ) )
{
var boolConverter = new CustomBooleanTypeConverter ( ) ;
if ( boolConverter . CanConvertFrom ( input . GetType ( ) ) )
{
2012-09-27 15:41:24 -02:00
try
{
2012-09-29 07:20:23 +07:00
var converted = boolConverter . ConvertFrom ( input ) ;
2013-09-11 08:22:28 +02:00
return Attempt . Succeed ( converted ) ;
2012-09-27 15:41:24 -02:00
}
catch ( Exception e )
{
2013-09-04 17:14:06 +02:00
return Attempt < object > . Fail ( e ) ;
2012-09-27 15:41:24 -02:00
}
2012-07-31 00:02:27 +06:00
}
}
2012-09-29 07:20:23 +07:00
var outputConverter = TypeDescriptor . GetConverter ( destinationType ) ;
if ( outputConverter . CanConvertFrom ( input . GetType ( ) ) )
2012-07-31 00:02:27 +06:00
{
2012-09-29 07:20:23 +07:00
try
2012-07-31 00:02:27 +06:00
{
2012-09-29 07:20:23 +07:00
var converted = outputConverter . ConvertFrom ( input ) ;
2013-09-11 08:22:28 +02:00
return Attempt . Succeed ( converted ) ;
2012-09-29 07:20:23 +07:00
}
catch ( Exception e )
{
2013-09-04 17:14:06 +02:00
return Attempt < object > . Fail ( e ) ;
2012-07-31 00:02:27 +06:00
}
}
2012-09-29 07:20:23 +07:00
if ( TypeHelper . IsTypeAssignableFrom < IConvertible > ( input ) )
2012-07-31 00:02:27 +06:00
{
2012-09-29 07:20:23 +07:00
try
{
var casted = Convert . ChangeType ( input , destinationType ) ;
2013-09-11 08:22:28 +02:00
return Attempt . Succeed ( casted ) ;
2012-09-29 07:20:23 +07:00
}
catch ( Exception e )
{
2013-09-04 17:14:06 +02:00
return Attempt < object > . Fail ( e ) ;
2012-09-29 07:20:23 +07:00
}
2012-07-31 00:02:27 +06:00
}
2013-09-04 17:14:06 +02:00
return Attempt < object > . Fail ( ) ;
2012-07-31 00:02:27 +06:00
}
2013-10-17 19:12:08 -05:00
private static Nullable < Attempt < object > > TryConvertToFromString ( this string input , Type destinationType )
{
if ( destinationType = = typeof ( string ) )
return Attempt < object > . Succeed ( input ) ;
2013-11-02 15:18:08 +11:00
if ( string . IsNullOrEmpty ( input ) )
2013-10-17 19:12:08 -05:00
{
if ( destinationType = = typeof ( Boolean ) )
return Attempt < object > . Succeed ( false ) ; // special case for booleans, null/empty == false
2013-11-02 15:18:08 +11:00
if ( destinationType = = typeof ( DateTime ) )
return Attempt < object > . Succeed ( DateTime . MinValue ) ;
2013-10-17 19:12:08 -05:00
}
// we have a non-empty string, look for type conversions in the expected order of frequency of use...
if ( destinationType . IsPrimitive )
{
2013-11-02 15:18:08 +11:00
if ( destinationType = = typeof ( Int32 ) )
2013-10-17 19:12:08 -05:00
{
Int32 value ;
return Int32 . TryParse ( input , out value ) ? Attempt < object > . Succeed ( value ) : Attempt < object > . Fail ( ) ;
}
2013-11-02 15:18:08 +11:00
if ( destinationType = = typeof ( Int64 ) )
{
Int64 value ;
return Int64 . TryParse ( input , out value ) ? Attempt < object > . Succeed ( value ) : Attempt < object > . Fail ( ) ;
}
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 ;
2014-03-06 09:14:05 +01:00
var input2 = NormalizeNumberDecimalSeparator ( input ) ;
return Double . TryParse ( input2 , out value ) ? Attempt < object > . Succeed ( value ) : Attempt < object > . Fail ( ) ;
2013-11-02 15:18:08 +11:00
}
else if ( destinationType = = typeof ( Single ) )
{
Single value ;
2014-03-06 09:14:05 +01:00
var input2 = NormalizeNumberDecimalSeparator ( input ) ;
return Single . TryParse ( input2 , out value ) ? Attempt < object > . Succeed ( value ) : Attempt < object > . Fail ( ) ;
2013-11-02 15:18:08 +11:00
}
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 ( ) ;
}
2013-10-17 19:12:08 -05:00
}
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 ;
2014-01-29 11:19:59 +11:00
if ( DateTime . TryParse ( input , out value ) )
{
switch ( value . Kind )
{
case DateTimeKind . Unspecified :
case DateTimeKind . Utc :
return Attempt < object > . Succeed ( value ) ;
case DateTimeKind . Local :
return Attempt < object > . Succeed ( value . ToUniversalTime ( ) ) ;
default :
throw new ArgumentOutOfRangeException ( ) ;
}
}
return Attempt < object > . Fail ( ) ;
2013-10-17 19:12:08 -05:00
}
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 ;
2014-03-06 09:14:05 +01:00
var input2 = NormalizeNumberDecimalSeparator ( input ) ;
return Decimal . TryParse ( input2 , out value ) ? Attempt < object > . Succeed ( value ) : Attempt < object > . Fail ( ) ;
2013-10-17 19:12:08 -05:00
}
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...
}
2014-03-06 09:14:05 +01:00
private readonly static char [ ] NumberDecimalSeparatorsToNormalize = new [ ] { '.' , ',' } ;
private static string NormalizeNumberDecimalSeparator ( string s )
{
var normalized = System . Threading . Thread . CurrentThread . CurrentUICulture . NumberFormat . NumberDecimalSeparator [ 0 ] ;
return s . ReplaceMany ( NumberDecimalSeparatorsToNormalize , normalized ) ;
}
2013-04-30 16:43:59 -10:00
internal static void CheckThrowObjectDisposed ( this IDisposable disposable , bool isDisposed , string objectname )
2012-07-31 00:02:27 +06:00
{
//TODO: Localise this exception
if ( isDisposed )
throw new ObjectDisposedException ( objectname ) ;
}
//public enum PropertyNamesCaseType
//{
// CamelCase,
// CaseInsensitive
//}
2012-09-29 07:20:23 +07:00
2012-07-31 00:02:27 +06:00
///// <summary>
///// Convert an object to a JSON string with camelCase formatting
///// </summary>
///// <param name="obj"></param>
///// <returns></returns>
//public static string ToJsonString(this object obj)
//{
// return obj.ToJsonString(PropertyNamesCaseType.CamelCase);
//}
///// <summary>
///// Convert an object to a JSON string with the specified formatting
///// </summary>
///// <param name="obj">The obj.</param>
///// <param name="propertyNamesCaseType">Type of the property names case.</param>
///// <returns></returns>
//public static string ToJsonString(this object obj, PropertyNamesCaseType propertyNamesCaseType)
//{
// var type = obj.GetType();
// var dateTimeStyle = "yyyy-MM-dd HH:mm:ss";
// if (type.IsPrimitive || typeof(string).IsAssignableFrom(type))
// {
// return obj.ToString();
// }
// if (typeof(DateTime).IsAssignableFrom(type) || typeof(DateTimeOffset).IsAssignableFrom(type))
// {
// return Convert.ToDateTime(obj).ToString(dateTimeStyle);
// }
// var serializer = new JsonSerializer();
// switch (propertyNamesCaseType)
// {
// case PropertyNamesCaseType.CamelCase:
// serializer.ContractResolver = new CamelCasePropertyNamesContractResolver();
// break;
// }
// var dateTimeConverter = new IsoDateTimeConverter
// {
// DateTimeStyles = System.Globalization.DateTimeStyles.None,
// DateTimeFormat = dateTimeStyle
// };
// if (typeof(IDictionary).IsAssignableFrom(type))
// {
// return JObject.FromObject(obj, serializer).ToString(Formatting.None, dateTimeConverter);
// }
// if (type.IsArray || (typeof(IEnumerable).IsAssignableFrom(type)))
// {
// return JArray.FromObject(obj, serializer).ToString(Formatting.None, dateTimeConverter);
// }
// return JObject.FromObject(obj, serializer).ToString(Formatting.None, dateTimeConverter);
//}
2012-09-29 07:20:23 +07:00
2012-07-31 00:02:27 +06:00
/// <summary>
/// Converts an object into a dictionary
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TProperty"></typeparam>
/// <typeparam name="TVal"> </typeparam>
/// <param name="o"></param>
/// <param name="ignoreProperties"></param>
/// <returns></returns>
2013-04-30 16:43:59 -10:00
internal static IDictionary < string , TVal > ToDictionary < T , TProperty , TVal > ( this T o ,
2012-09-29 07:20:23 +07:00
params Expression < Func < T , TProperty > > [ ] ignoreProperties )
2012-07-31 00:02:27 +06:00
{
return o . ToDictionary < TVal > ( ignoreProperties . Select ( e = > o . GetPropertyInfo ( e ) ) . Select ( propInfo = > propInfo . Name ) . ToArray ( ) ) ;
}
/// <summary>
/// Turns object into dictionary
/// </summary>
/// <param name="o"></param>
/// <param name="ignoreProperties">Properties to ignore</param>
/// <returns></returns>
2013-04-30 16:43:59 -10:00
internal static IDictionary < string , TVal > ToDictionary < TVal > ( this object o , params string [ ] ignoreProperties )
2012-07-31 00:02:27 +06:00
{
if ( o ! = null )
{
var props = TypeDescriptor . GetProperties ( o ) ;
var d = new Dictionary < string , TVal > ( ) ;
foreach ( var prop in props . Cast < PropertyDescriptor > ( ) . Where ( x = > ! ignoreProperties . Contains ( x . Name ) ) )
{
var val = prop . GetValue ( o ) ;
if ( val ! = null )
{
d . Add ( prop . Name , ( TVal ) val ) ;
}
}
return d ;
}
return new Dictionary < string , TVal > ( ) ;
}
2013-04-30 16:43:59 -10:00
internal static string ToDebugString ( this object obj , int levels = 0 )
2012-07-31 00:02:27 +06:00
{
if ( obj = = null ) return "{null}" ;
try
{
if ( obj is string )
{
return "\"{0}\"" . InvariantFormat ( obj ) ;
}
2013-10-17 19:12:08 -05:00
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? )
2012-07-31 00:02:27 +06:00
{
return "{0}" . InvariantFormat ( obj ) ;
}
if ( obj is Enum )
{
return "[{0}]" . InvariantFormat ( obj ) ;
}
if ( obj is IEnumerable )
{
var enumerable = ( obj as IEnumerable ) ;
var items = ( from object enumItem in enumerable let value = GetEnumPropertyDebugString ( enumItem , levels ) where value ! = null select value ) . Take ( 10 ) . ToList ( ) ;
return items . Count ( ) > 0
2012-09-29 07:20:23 +07:00
? "{{ {0} }}" . InvariantFormat ( String . Join ( ", " , items ) )
: null ;
2012-07-31 00:02:27 +06:00
}
var props = obj . GetType ( ) . GetProperties ( ) ;
if ( ( props . Count ( ) = = 2 ) & & props [ 0 ] . Name = = "Key" & & props [ 1 ] . Name = = "Value" & & levels > - 2 )
{
try
{
var key = props [ 0 ] . GetValue ( obj , null ) as string ;
var value = props [ 1 ] . GetValue ( obj , null ) . ToDebugString ( levels - 1 ) ;
return "{0}={1}" . InvariantFormat ( key , value ) ;
}
catch ( Exception )
{
return "[KeyValuePropertyException]" ;
}
}
if ( levels > - 1 )
{
var items =
from propertyInfo in props
let value = GetPropertyDebugString ( propertyInfo , obj , levels )
where value ! = null
select "{0}={1}" . InvariantFormat ( propertyInfo . Name , value ) ;
return items . Count ( ) > 0
2012-09-29 07:20:23 +07:00
? "[{0}]:{{ {1} }}" . InvariantFormat ( obj . GetType ( ) . Name , String . Join ( ", " , items ) )
: null ;
2012-07-31 00:02:27 +06:00
}
}
catch ( Exception ex )
{
return "[Exception:{0}]" . InvariantFormat ( ex . Message ) ;
}
return null ;
}
/// <summary>
/// Attempts to serialize the value to an XmlString using ToXmlString
/// </summary>
/// <param name="value"></param>
/// <param name="type"></param>
/// <returns></returns>
2013-04-30 16:43:59 -10:00
internal static Attempt < string > TryConvertToXmlString ( this object value , Type type )
2012-07-31 00:02:27 +06:00
{
try
{
var output = value . ToXmlString ( type ) ;
2013-09-11 08:22:28 +02:00
return Attempt . Succeed ( output ) ;
2012-07-31 00:02:27 +06:00
}
catch ( NotSupportedException ex )
{
2013-09-04 17:14:06 +02:00
return Attempt < string > . Fail ( ex ) ;
2012-07-31 00:02:27 +06:00
}
}
/// <summary>
/// Returns an XmlSerialized safe string representation for the value
/// </summary>
/// <param name="value"></param>
/// <param name="type">The Type can only be a primitive type or Guid and byte[] otherwise an exception is thrown</param>
/// <returns></returns>
2013-04-30 16:43:59 -10:00
internal static string ToXmlString ( this object value , Type type )
2012-07-31 00:02:27 +06:00
{
2013-08-21 14:13:22 +10:00
if ( value = = null ) return string . Empty ;
2013-08-12 18:09:16 +10:00
if ( type = = typeof ( string ) ) return ( value . ToString ( ) . IsNullOrWhiteSpace ( ) ? "" : value . ToString ( ) ) ;
2012-07-31 00:02:27 +06:00
if ( type = = typeof ( bool ) ) return XmlConvert . ToString ( ( bool ) value ) ;
if ( type = = typeof ( byte ) ) return XmlConvert . ToString ( ( byte ) value ) ;
if ( type = = typeof ( char ) ) return XmlConvert . ToString ( ( char ) value ) ;
2014-01-29 11:19:59 +11:00
if ( type = = typeof ( DateTime ) ) return XmlConvert . ToString ( ( DateTime ) value , XmlDateTimeSerializationMode . Unspecified ) ;
2012-07-31 00:02:27 +06:00
if ( type = = typeof ( DateTimeOffset ) ) return XmlConvert . ToString ( ( DateTimeOffset ) value ) ;
if ( type = = typeof ( decimal ) ) return XmlConvert . ToString ( ( decimal ) value ) ;
if ( type = = typeof ( double ) ) return XmlConvert . ToString ( ( double ) value ) ;
if ( type = = typeof ( float ) ) return XmlConvert . ToString ( ( float ) value ) ;
if ( type = = typeof ( Guid ) ) return XmlConvert . ToString ( ( Guid ) value ) ;
if ( type = = typeof ( int ) ) return XmlConvert . ToString ( ( int ) value ) ;
if ( type = = typeof ( long ) ) return XmlConvert . ToString ( ( long ) value ) ;
if ( type = = typeof ( sbyte ) ) return XmlConvert . ToString ( ( sbyte ) value ) ;
if ( type = = typeof ( short ) ) return XmlConvert . ToString ( ( short ) value ) ;
if ( type = = typeof ( TimeSpan ) ) return XmlConvert . ToString ( ( TimeSpan ) value ) ;
if ( type = = typeof ( bool ) ) return XmlConvert . ToString ( ( bool ) value ) ;
if ( type = = typeof ( uint ) ) return XmlConvert . ToString ( ( uint ) value ) ;
if ( type = = typeof ( ulong ) ) return XmlConvert . ToString ( ( ulong ) value ) ;
if ( type = = typeof ( ushort ) ) return XmlConvert . ToString ( ( ushort ) value ) ;
throw new NotSupportedException ( "Cannot convert type " + type . FullName + " to a string using ToXmlString as it is not supported by XmlConvert" ) ;
}
2013-05-27 21:32:37 -10:00
/// <summary>
/// Returns an XmlSerialized safe string representation for the value and type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
internal static string ToXmlString < T > ( this object value )
{
return value . ToXmlString ( typeof ( T ) ) ;
}
private static string GetEnumPropertyDebugString ( object enumItem , int levels )
2012-07-31 00:02:27 +06:00
{
try
{
return enumItem . ToDebugString ( levels - 1 ) ;
}
catch ( Exception )
{
return "[GetEnumPartException]" ;
}
}
private static string GetPropertyDebugString ( PropertyInfo propertyInfo , object obj , int levels )
{
try
{
return propertyInfo . GetValue ( obj , null ) . ToDebugString ( levels - 1 ) ;
}
catch ( Exception )
{
return "[GetPropertyValueException]" ;
}
}
}
}