using System.Collections; using System.Collections.Generic; using System; using System.Reflection; using System.Text.RegularExpressions; namespace Rokojori { public class ReflectionHelper { public static Type GetTypeByNameFromAssembly( string name, Assembly assembly ) { var type = assembly.GetType( name ); if ( type != null ) { return type; } var types = assembly.GetTypes(); var genericEndingRegex = @"`\d+$"; for ( int i = 0; i < types.Length; i++ ) { var typeName = types[ i ].Name; var isGeneric = Regex.IsMatch( typeName, genericEndingRegex ); if ( ! isGeneric ) { continue; } var typeNameWithoutGeneric = Regex.Replace( typeName, genericEndingRegex, "" ); if ( typeNameWithoutGeneric == name ) { return types[ i ]; } } return null; } public static Type GetTypeByName( string name ) { var assemblies = new List(); assemblies.AddRange( AppDomain.CurrentDomain.GetAssemblies() ); assemblies.Reverse(); var assembly = assemblies.Find( a => a.GetType( name ) != null ); return assembly == null ? null : assembly.GetType( name ); } public static bool IsList( Type type ) { if ( ! ( type.IsGenericType ) ) { return false; } return type.GetGenericTypeDefinition().IsAssignableFrom( typeof( List<> ) ); } public static bool IsList( object objectValue ) { if ( objectValue == null ) { return false; } if ( ! ( objectValue is IList ) ) { return false; } return IsList( objectValue.GetType() ); } public static bool IsDictionary( Type type ) { if ( ! ( type.IsGenericType ) ) { return false; } return type.GetGenericTypeDefinition().IsAssignableFrom( typeof( Dictionary<,> ) ); } public static bool IsDictionary( object objectValue ) { if ( objectValue == null ) { return false; } if ( ! ( objectValue is IDictionary ) ) { return false; } return IsDictionary( objectValue.GetType() ); } public static string GetMemberName( object obj, object member ) { if ( obj == null || member == null ) { return null; } var type = obj.GetType(); var fields = type.GetFields(); for ( int i = 0; i < fields.Length; i++ ) { var value = fields[ i ].GetValue( obj ); if ( value == member ) { return fields[ i ].Name; } } return null; } public static List GetFieldInfosOfType( object instance ) where T:class { var type = instance.GetType(); var fields = type.GetFields(); var list = new List(); for ( int i = 0; i < fields.Length; i++ ) { var value = fields[ i ].GetValue( instance ); var tValue = value as T; if ( tValue != null ) { list.Add( fields[ i ] ); } } return list; } public static List GetFieldValuesOfType( object instance ) where T:class { var type = instance.GetType(); var fields = type.GetFields(); var list = new List(); for ( int i = 0; i < fields.Length; i++ ) { var value = fields[ i ].GetValue( instance ); var tValue = value as T; if ( tValue != null ) { list.Add( tValue ); } } return list; } public static void GetFields( System.Action action ) { GetFields( typeof( C ), action ); } public static void GetFields( System.Type c, System.Action action ) { var fields = c.GetFields(); foreach( var f in fields ) { if ( f.FieldType == typeof( T ) ) { action( f ); } } } public static FieldInfo GetFieldInfo( object instance, string memberName ) { var type = instance.GetType(); var fields = type.GetFields(); var index = -1; for ( int i = 0; i < fields.Length; i++ ) { if ( fields[ i ].Name == memberName ) { index = i; } } return index == -1 ? null : fields[ index ]; } public static List GetDataMemberInfos( object instance ) { var list = GetDataMemberInfos( instance, BindingFlags.Instance | BindingFlags.Public ); list = Lists.Filter( list, m => IsType( m ) ); return list; } public static bool IsTypeOneOf( T instance, params Type[] types ) { if ( instance == null ) { return false; } var type = instance.GetType(); for ( int i = 0; i < types.Length; i++ ) { if ( type.IsAssignableFrom( types[ i ] ) ) { return true; } } return false; } public static bool IsType( MemberInfo mi ) { if ( mi is FieldInfo fi ) { return fi.FieldType == typeof( T ); } if ( mi is PropertyInfo pi ) { return pi.PropertyType == typeof( T ); } return false; } public static List GetDataMemberInfos( object instance, BindingFlags flags ) { var list = new List(); var type = instance.GetType(); var fields = type.GetFields( flags ); for ( int i = 0; i < fields.Length; i++ ) { list.Add( fields[ i ] ); } var properties = type.GetProperties( flags ); for ( int i = 0; i < properties.Length; i++ ) { list.Add( properties[ i ] ); } return list; } public static List GetDataMemberInfos( BindingFlags flags = defaultBindings ) { var list = new List(); var type = typeof( T ); var fields = type.GetFields( flags ); for ( int i = 0; i < fields.Length; i++ ) { list.Add( fields[ i ] ); } var properties = type.GetProperties( flags | BindingFlags.GetProperty | BindingFlags.SetProperty ); for ( int i = 0; i < properties.Length; i++ ) { list.Add( properties[ i ] ); RJLog.Log( properties[ i ].Name ); } return list; } public static List GetDataMemberValues( object instance ) { var infos = GetDataMemberInfos( instance ); return Lists.Map( infos, i => GetDataMemberValue( instance, i ) ); } public static MemberInfo GetDataMemberInfo( object instance, string memberName, BindingFlags flags = BindingFlags.Public | BindingFlags.Instance ) { var type = instance.GetType(); var fieldInfo = type.GetField( memberName, flags ); if ( fieldInfo != null ) { return fieldInfo; } return type.GetProperty( memberName, flags ); } public const BindingFlags defaultBindings = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; public static bool HasDataMember( object instance, string memberName, BindingFlags flags = ReflectionHelper.defaultBindings ) { return GetDataMemberInfo( instance, memberName, flags ) != null; } public static T GetDataMemberValue( object instance, MemberInfo info ) { if ( info == null ) { return default(T); } if ( info is FieldInfo fieldInfo ) { return (T) fieldInfo.GetValue( instance ); } if ( info is PropertyInfo propertyInfo ) { return (T) propertyInfo.GetValue( instance ); } return default(T); } public static T GetDataMemberValue( object instance, string memberName, BindingFlags flags = ReflectionHelper.defaultBindings ) { return GetDataMemberValue( instance, GetDataMemberInfo( instance, memberName, flags ) ); } public static void SetDataMemberValue( object instance, string memberName, object value, BindingFlags flags = ReflectionHelper.defaultBindings ) { var info = GetDataMemberInfo( instance, memberName, flags ); if ( info == null ) { return; } if ( info is FieldInfo fieldInfo ) { fieldInfo.SetValue( instance, value ); } if ( info is PropertyInfo propertyInfo ) { propertyInfo.SetValue( instance, value ); } } public static void CopyDataMembersFromTo( object source, object target, List dataMembers ) { dataMembers.ForEach( dm => { var value = GetDataMemberValue( source, dm ); SetDataMemberValue( target, dm, value ); } ); } } }