2025-07-08 10:46:31 +00:00
using System.Collections ;
using System.Collections.Generic ;
using System ;
using System.Linq ;
using System.Reflection ;
using System.ComponentModel ;
using UnityEngine ;
using ES3Types ;
namespace ES3Internal
{
public static class ES3Reflection
{
public const string memberFieldPrefix = "m_" ;
public const string componentTagFieldName = "tag" ;
public const string componentNameFieldName = "name" ;
public static readonly string [ ] excludedPropertyNames = new string [ ] { "runInEditMode" , "useGUILayout" , "hideFlags" } ;
public static readonly Type serializableAttributeType = typeof ( System . SerializableAttribute ) ;
public static readonly Type serializeFieldAttributeType = typeof ( SerializeField ) ;
public static readonly Type obsoleteAttributeType = typeof ( System . ObsoleteAttribute ) ;
public static readonly Type nonSerializedAttributeType = typeof ( System . NonSerializedAttribute ) ;
public static readonly Type es3SerializableAttributeType = typeof ( ES3Serializable ) ;
public static readonly Type es3NonSerializableAttributeType = typeof ( ES3NonSerializable ) ;
public static Type [ ] EmptyTypes = new Type [ 0 ] ;
private static Assembly [ ] _assemblies = null ;
private static Assembly [ ] Assemblies
{
get
{
if ( _assemblies = = null )
{
var assemblyNames = new ES3Settings ( ) . assemblyNames ;
var assemblyList = new List < Assembly > ( ) ;
/* We only use a try/catch block for UWP because exceptions can be disabled on some other platforms (e.g. WebGL), but the non-try/catch method doesn't work on UWP */
#if NETFX_CORE
for ( int i = 0 ; i < assemblyNames . Length ; i + + )
{
try
{
var assembly = Assembly . Load ( new AssemblyName ( assemblyNames [ i ] ) ) ;
if ( assembly ! = null )
assemblyList . Add ( assembly ) ;
}
catch { }
}
#else
var assemblies = AppDomain . CurrentDomain . GetAssemblies ( ) ;
foreach ( var assembly in assemblies )
{
// This try/catch block is here to catch errors such as assemblies containing double-byte characters in their path.
// This obviously won't work if exceptions are disabled.
try
{
if ( assemblyNames . Contains ( assembly . GetName ( ) . Name ) )
{
assemblyList . Add ( assembly ) ;
}
}
catch { }
}
#endif
_assemblies = assemblyList . ToArray ( ) ;
}
return _assemblies ;
}
}
public static ConstructorInfo GetConstructor ( Type type , Type [ ] parameters )
{
return type . GetTypeInfo ( ) . GetConstructor ( parameters ) ;
}
/ *
* Gets the element type of a collection or array .
* Returns null if type is not a collection type .
* /
public static Type [ ] GetElementTypes ( Type type )
{
if ( IsGenericType ( type ) )
return ES3Reflection . GetGenericArguments ( type ) ;
else if ( type . IsArray )
return new Type [ ] { ES3Reflection . GetElementType ( type ) } ;
else
return null ;
}
public static List < FieldInfo > GetSerializableFields ( Type type , List < FieldInfo > serializableFields = null , bool safe = true , string [ ] memberNames = null , BindingFlags bindings = BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance | BindingFlags . Static | BindingFlags . DeclaredOnly )
{
if ( type = = null )
return new List < FieldInfo > ( ) ;
var fields = type . GetFields ( bindings ) ;
if ( serializableFields = = null )
serializableFields = new List < FieldInfo > ( ) ;
foreach ( var field in fields )
{
var fieldName = field . Name ;
// If a members array was provided as a parameter, only include the field if it's in the array.
if ( memberNames ! = null )
if ( ! memberNames . Contains ( fieldName ) )
continue ;
var fieldType = field . FieldType ;
if ( AttributeIsDefined ( field , es3SerializableAttributeType ) )
{
serializableFields . Add ( field ) ;
continue ;
}
if ( AttributeIsDefined ( field , es3NonSerializableAttributeType ) )
continue ;
if ( safe )
{
// If the field is private, only serialize it if it's explicitly marked as serializable.
if ( ! field . IsPublic & & ! AttributeIsDefined ( field , serializeFieldAttributeType ) )
continue ;
}
// Exclude const or readonly fields.
if ( field . IsLiteral | | field . IsInitOnly )
continue ;
// Don't store fields whose type is the same as the class the field is housed in unless it's stored by reference (to prevent cyclic references)
if ( fieldType = = type & & ! IsAssignableFrom ( typeof ( UnityEngine . Object ) , fieldType ) )
continue ;
// If property is marked as obsolete or non-serialized, don't serialize it.
if ( AttributeIsDefined ( field , nonSerializedAttributeType ) | | AttributeIsDefined ( field , obsoleteAttributeType ) )
continue ;
if ( ! TypeIsSerializable ( field . FieldType ) )
continue ;
// Don't serialize member fields of Unity classes unless they have the SerializeField attribute.
if ( safe & & field . DeclaringType . Namespace ! = null & & fieldName . StartsWith ( memberFieldPrefix ) & & ! AttributeIsDefined ( field , serializeFieldAttributeType ) & & field . DeclaringType . Namespace . Contains ( "UnityEngine" ) )
continue ;
serializableFields . Add ( field ) ;
}
var baseType = BaseType ( type ) ;
if ( baseType ! = null & & baseType ! = typeof ( System . Object ) & & baseType ! = typeof ( UnityEngine . Object ) )
GetSerializableFields ( BaseType ( type ) , serializableFields , safe , memberNames ) ;
return serializableFields ;
}
public static List < PropertyInfo > GetSerializableProperties ( Type type , List < PropertyInfo > serializableProperties = null , bool safe = true , string [ ] memberNames = null , BindingFlags bindings = BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance | BindingFlags . Static | BindingFlags . DeclaredOnly )
{
bool isComponent = IsAssignableFrom ( typeof ( UnityEngine . Component ) , type ) ;
// Only get private properties if we're not getting properties safely.
if ( ! safe )
bindings = bindings | BindingFlags . NonPublic ;
var properties = type . GetProperties ( bindings ) ;
if ( serializableProperties = = null )
serializableProperties = new List < PropertyInfo > ( ) ;
foreach ( var p in properties )
{
if ( AttributeIsDefined ( p , es3SerializableAttributeType ) )
{
serializableProperties . Add ( p ) ;
continue ;
}
if ( AttributeIsDefined ( p , es3NonSerializableAttributeType ) )
continue ;
var propertyName = p . Name ;
if ( excludedPropertyNames . Contains ( propertyName ) )
continue ;
// If a members array was provided as a parameter, only include the property if it's in the array.
if ( memberNames ! = null )
if ( ! memberNames . Contains ( propertyName ) )
continue ;
if ( safe )
{
// If safe serialization is enabled, only get properties which are explicitly marked as serializable.
if ( ! AttributeIsDefined ( p , serializeFieldAttributeType ) & & ! AttributeIsDefined ( p , es3SerializableAttributeType ) )
continue ;
}
var propertyType = p . PropertyType ;
// Don't store properties whose type is the same as the class the property is housed in unless it's stored by reference (to prevent cyclic references)
if ( propertyType = = type & & ! IsAssignableFrom ( typeof ( UnityEngine . Object ) , propertyType ) )
continue ;
if ( ! p . CanRead | | ! p . CanWrite )
continue ;
// Only support properties with indexing if they're an array.
if ( p . GetIndexParameters ( ) . Length ! = 0 & & ! propertyType . IsArray )
continue ;
// Check that the type of the property is one which we can serialize.
// Also check whether an ES3Type exists for it.
if ( ! TypeIsSerializable ( propertyType ) )
continue ;
// Ignore certain properties on components.
if ( isComponent )
{
// Ignore properties which are accessors for GameObject fields.
if ( propertyName = = componentTagFieldName | | propertyName = = componentNameFieldName )
continue ;
}
// If property is marked as obsolete or non-serialized, don't serialize it.
if ( AttributeIsDefined ( p , obsoleteAttributeType ) | | AttributeIsDefined ( p , nonSerializedAttributeType ) )
continue ;
serializableProperties . Add ( p ) ;
}
var baseType = BaseType ( type ) ;
if ( baseType ! = null & & baseType ! = typeof ( System . Object ) )
GetSerializableProperties ( baseType , serializableProperties , safe , memberNames ) ;
return serializableProperties ;
}
public static bool TypeIsSerializable ( Type type )
{
if ( type = = null )
return false ;
if ( AttributeIsDefined ( type , es3NonSerializableAttributeType ) )
return false ;
if ( IsPrimitive ( type ) | | IsValueType ( type ) | | IsAssignableFrom ( typeof ( UnityEngine . Component ) , type ) | | IsAssignableFrom ( typeof ( UnityEngine . ScriptableObject ) , type ) )
return true ;
var es3Type = ES3TypeMgr . GetOrCreateES3Type ( type , false ) ;
if ( es3Type ! = null & & ! es3Type . isUnsupported )
return true ;
if ( TypeIsArray ( type ) )
{
if ( TypeIsSerializable ( type . GetElementType ( ) ) )
return true ;
return false ;
}
var genericArgs = type . GetGenericArguments ( ) ;
for ( int i = 0 ; i < genericArgs . Length ; i + + )
if ( ! TypeIsSerializable ( genericArgs [ i ] ) )
return false ;
/ * if ( HasParameterlessConstructor ( type ) )
return true ; * /
return false ;
}
public static System . Object CreateInstance ( Type type )
{
if ( IsAssignableFrom ( typeof ( UnityEngine . Component ) , type ) )
return ES3ComponentType . CreateComponent ( type ) ;
else if ( IsAssignableFrom ( typeof ( ScriptableObject ) , type ) )
return ScriptableObject . CreateInstance ( type ) ;
else if ( ES3Reflection . HasParameterlessConstructor ( type ) )
return Activator . CreateInstance ( type ) ;
else
{
#if NETFX_CORE
throw new NotSupportedException ( $"Cannot create an instance of {type} because it does not have a parameterless constructor, which is required on Universal Windows platform." ) ;
#else
return System . Runtime . Serialization . FormatterServices . GetUninitializedObject ( type ) ;
#endif
}
}
public static System . Object CreateInstance ( Type type , params object [ ] args )
{
if ( IsAssignableFrom ( typeof ( UnityEngine . Component ) , type ) )
return ES3ComponentType . CreateComponent ( type ) ;
else if ( IsAssignableFrom ( typeof ( ScriptableObject ) , type ) )
return ScriptableObject . CreateInstance ( type ) ;
return Activator . CreateInstance ( type , args ) ;
}
public static Array ArrayCreateInstance ( Type type , int length )
{
return Array . CreateInstance ( type , new int [ ] { length } ) ;
}
public static Array ArrayCreateInstance ( Type type , int [ ] dimensions )
{
return Array . CreateInstance ( type , dimensions ) ;
}
public static Type MakeGenericType ( Type type , Type genericParam )
{
return type . MakeGenericType ( genericParam ) ;
}
public static ES3ReflectedMember [ ] GetSerializableMembers ( Type type , bool safe = true , string [ ] memberNames = null )
{
if ( type = = null )
return new ES3ReflectedMember [ 0 ] ;
var fieldInfos = GetSerializableFields ( type , new List < FieldInfo > ( ) , safe , memberNames ) ;
var propertyInfos = GetSerializableProperties ( type , new List < PropertyInfo > ( ) , safe , memberNames ) ;
var reflectedFields = new ES3ReflectedMember [ fieldInfos . Count + propertyInfos . Count ] ;
for ( int i = 0 ; i < fieldInfos . Count ; i + + )
reflectedFields [ i ] = new ES3ReflectedMember ( fieldInfos [ i ] ) ;
for ( int i = 0 ; i < propertyInfos . Count ; i + + )
reflectedFields [ i + fieldInfos . Count ] = new ES3ReflectedMember ( propertyInfos [ i ] ) ;
return reflectedFields ;
}
public static ES3ReflectedMember GetES3ReflectedProperty ( Type type , string propertyName )
{
var propertyInfo = ES3Reflection . GetProperty ( type , propertyName ) ;
return new ES3ReflectedMember ( propertyInfo ) ;
}
public static ES3ReflectedMember GetES3ReflectedMember ( Type type , string fieldName )
{
var fieldInfo = ES3Reflection . GetField ( type , fieldName ) ;
return new ES3ReflectedMember ( fieldInfo ) ;
}
/ *
* Finds all classes of a specific type , and then returns an instance of each .
* Ignores classes which can ' t be instantiated ( i . e . abstract classes , those without parameterless constructors ) .
* /
public static IList < T > GetInstances < T > ( )
{
var instances = new List < T > ( ) ;
foreach ( var assembly in Assemblies )
foreach ( var type in assembly . GetTypes ( ) )
if ( IsAssignableFrom ( typeof ( T ) , type ) & & ES3Reflection . HasParameterlessConstructor ( type ) & & ! ES3Reflection . IsAbstract ( type ) )
instances . Add ( ( T ) Activator . CreateInstance ( type ) ) ;
return instances ;
}
public static IList < Type > GetDerivedTypes ( Type derivedType )
{
return
(
from assembly in Assemblies
from type in assembly . GetTypes ( )
where IsAssignableFrom ( derivedType , type )
select type
) . ToList ( ) ;
}
public static bool IsAssignableFrom ( Type a , Type b )
{
return a . IsAssignableFrom ( b ) ;
}
public static Type GetGenericTypeDefinition ( Type type )
{
return type . GetGenericTypeDefinition ( ) ;
}
public static Type [ ] GetGenericArguments ( Type type )
{
return type . GetGenericArguments ( ) ;
}
public static int GetArrayRank ( Type type )
{
return type . GetArrayRank ( ) ;
}
public static string GetAssemblyQualifiedName ( Type type )
{
return type . AssemblyQualifiedName ;
}
public static ES3ReflectedMethod GetMethod ( Type type , string methodName , Type [ ] genericParameters , Type [ ] parameterTypes )
{
return new ES3ReflectedMethod ( type , methodName , genericParameters , parameterTypes ) ;
}
public static bool TypeIsArray ( Type type )
{
return type . IsArray ;
}
public static Type GetElementType ( Type type )
{
return type . GetElementType ( ) ;
}
#if NETFX_CORE
public static bool IsAbstract ( Type type )
{
return type . GetTypeInfo ( ) . IsAbstract ;
}
public static bool IsInterface ( Type type )
{
return type . GetTypeInfo ( ) . IsInterface ;
}
public static bool IsGenericType ( Type type )
{
return type . GetTypeInfo ( ) . IsGenericType ;
}
public static bool IsValueType ( Type type )
{
return type . GetTypeInfo ( ) . IsValueType ;
}
public static bool IsEnum ( Type type )
{
return type . GetTypeInfo ( ) . IsEnum ;
}
public static bool HasParameterlessConstructor ( Type type )
{
return GetParameterlessConstructor ( type ) ! = null ;
}
public static ConstructorInfo GetParameterlessConstructor ( Type type )
{
foreach ( var cInfo in type . GetTypeInfo ( ) . DeclaredConstructors )
if ( ! cInfo . IsStatic & & cInfo . GetParameters ( ) . Length = = 0 )
return cInfo ;
return null ;
}
public static string GetShortAssemblyQualifiedName ( Type type )
{
if ( IsPrimitive ( type ) )
return type . ToString ( ) ;
return type . FullName + "," + type . GetTypeInfo ( ) . Assembly . GetName ( ) . Name ;
}
public static PropertyInfo GetProperty ( Type type , string propertyName )
{
var property = type . GetTypeInfo ( ) . GetDeclaredProperty ( propertyName ) ;
if ( property = = null & & type . BaseType ! = typeof ( object ) )
return GetProperty ( type . BaseType , propertyName ) ;
return property ;
}
public static FieldInfo GetField ( Type type , string fieldName )
{
return type . GetTypeInfo ( ) . GetDeclaredField ( fieldName ) ;
}
public static MethodInfo [ ] GetMethods ( Type type , string methodName )
{
return type . GetTypeInfo ( ) . GetDeclaredMethods ( methodName ) ;
}
public static bool IsPrimitive ( Type type )
{
return ( type . GetTypeInfo ( ) . IsPrimitive | | type = = typeof ( string ) | | type = = typeof ( decimal ) ) ;
}
public static bool AttributeIsDefined ( MemberInfo info , Type attributeType )
{
var attributes = info . GetCustomAttributes ( attributeType , true ) ;
foreach ( var attribute in attributes )
return true ;
return false ;
}
public static bool AttributeIsDefined ( Type type , Type attributeType )
{
var attributes = type . GetTypeInfo ( ) . GetCustomAttributes ( attributeType , true ) ;
foreach ( var attribute in attributes )
return true ;
return false ;
}
public static bool ImplementsInterface ( Type type , Type interfaceType )
{
return type . GetTypeInfo ( ) . ImplementedInterfaces . Contains ( interfaceType ) ;
}
public static Type BaseType ( Type type )
{
return type . GetTypeInfo ( ) . BaseType ;
}
#else
public static bool IsAbstract ( Type type )
{
return type . IsAbstract ;
}
public static bool IsInterface ( Type type )
{
return type . IsInterface ;
}
public static bool IsGenericType ( Type type )
{
return type . IsGenericType ;
}
public static bool IsValueType ( Type type )
{
return type . IsValueType ;
}
public static bool IsEnum ( Type type )
{
return type . IsEnum ;
}
public static bool HasParameterlessConstructor ( Type type )
{
if ( IsValueType ( type ) | | GetParameterlessConstructor ( type ) ! = null )
return true ;
return false ;
}
public static ConstructorInfo GetParameterlessConstructor ( Type type )
{
var constructors = type . GetConstructors ( BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic ) ;
foreach ( var constructor in constructors )
if ( constructor . GetParameters ( ) . Length = = 0 )
return constructor ;
return null ;
}
public static string GetShortAssemblyQualifiedName ( Type type )
{
if ( IsPrimitive ( type ) )
return type . ToString ( ) ;
return type . FullName + "," + type . Assembly . GetName ( ) . Name ;
}
public static PropertyInfo GetProperty ( Type type , string propertyName )
{
var property = type . GetProperty ( propertyName , BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance ) ;
if ( property = = null & & BaseType ( type ) ! = typeof ( object ) )
return GetProperty ( BaseType ( type ) , propertyName ) ;
return property ;
}
public static FieldInfo GetField ( Type type , string fieldName )
{
var field = type . GetField ( fieldName , BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance ) ;
if ( field = = null & & BaseType ( type ) ! = typeof ( object ) )
return GetField ( BaseType ( type ) , fieldName ) ;
return field ;
}
public static MethodInfo [ ] GetMethods ( Type type , string methodName )
{
return type . GetMethods ( ) . Where ( t = > t . Name = = methodName ) . ToArray ( ) ;
}
public static bool IsPrimitive ( Type type )
{
return ( type . IsPrimitive | | type = = typeof ( string ) | | type = = typeof ( decimal ) ) ;
}
public static bool AttributeIsDefined ( MemberInfo info , Type attributeType )
{
return Attribute . IsDefined ( info , attributeType , true ) ;
}
public static bool AttributeIsDefined ( Type type , Type attributeType )
{
return type . IsDefined ( attributeType , true ) ;
}
public static bool ImplementsInterface ( Type type , Type interfaceType )
{
return ( type . GetInterface ( interfaceType . Name ) ! = null ) ;
}
public static Type BaseType ( Type type )
{
return type . BaseType ;
}
public static Type GetType ( string typeString )
{
switch ( typeString )
{
case "bool" :
return typeof ( bool ) ;
case "byte" :
return typeof ( byte ) ;
case "sbyte" :
return typeof ( sbyte ) ;
case "char" :
return typeof ( char ) ;
case "decimal" :
return typeof ( decimal ) ;
case "double" :
return typeof ( double ) ;
case "float" :
return typeof ( float ) ;
case "int" :
return typeof ( int ) ;
case "uint" :
return typeof ( uint ) ;
case "long" :
return typeof ( long ) ;
case "ulong" :
return typeof ( ulong ) ;
case "short" :
return typeof ( short ) ;
case "ushort" :
return typeof ( ushort ) ;
case "string" :
return typeof ( string ) ;
case "Vector2" :
return typeof ( Vector2 ) ;
case "Vector3" :
return typeof ( Vector3 ) ;
case "Vector4" :
return typeof ( Vector4 ) ;
case "Color" :
return typeof ( Color ) ;
case "Transform" :
return typeof ( Transform ) ;
case "Component" :
return typeof ( UnityEngine . Component ) ;
case "GameObject" :
return typeof ( GameObject ) ;
case "MeshFilter" :
return typeof ( MeshFilter ) ;
case "Material" :
return typeof ( Material ) ;
case "Texture2D" :
return typeof ( Texture2D ) ;
case "UnityEngine.Object" :
return typeof ( UnityEngine . Object ) ;
case "System.Object" :
return typeof ( object ) ;
default :
return Type . GetType ( typeString ) ;
}
}
public static string GetTypeString ( Type type )
{
if ( type = = typeof ( bool ) )
return "bool" ;
else if ( type = = typeof ( byte ) )
return "byte" ;
else if ( type = = typeof ( sbyte ) )
return "sbyte" ;
else if ( type = = typeof ( char ) )
return "char" ;
else if ( type = = typeof ( decimal ) )
return "decimal" ;
else if ( type = = typeof ( double ) )
return "double" ;
else if ( type = = typeof ( float ) )
return "float" ;
else if ( type = = typeof ( int ) )
return "int" ;
else if ( type = = typeof ( uint ) )
return "uint" ;
else if ( type = = typeof ( long ) )
return "long" ;
else if ( type = = typeof ( ulong ) )
return "ulong" ;
else if ( type = = typeof ( short ) )
return "short" ;
else if ( type = = typeof ( ushort ) )
return "ushort" ;
else if ( type = = typeof ( string ) )
return "string" ;
else if ( type = = typeof ( Vector2 ) )
return "Vector2" ;
else if ( type = = typeof ( Vector3 ) )
return "Vector3" ;
else if ( type = = typeof ( Vector4 ) )
return "Vector4" ;
else if ( type = = typeof ( Color ) )
return "Color" ;
else if ( type = = typeof ( Transform ) )
return "Transform" ;
else if ( type = = typeof ( UnityEngine . Component ) )
return "Component" ;
else if ( type = = typeof ( GameObject ) )
return "GameObject" ;
else if ( type = = typeof ( MeshFilter ) )
return "MeshFilter" ;
else if ( type = = typeof ( Material ) )
return "Material" ;
else if ( type = = typeof ( Texture2D ) )
return "Texture2D" ;
else if ( type = = typeof ( UnityEngine . Object ) )
return "UnityEngine.Object" ;
else if ( type = = typeof ( object ) )
return "System.Object" ;
else
return GetShortAssemblyQualifiedName ( type ) ;
}
#endif
/ *
* Allows us to use FieldInfo and PropertyInfo interchangably .
* /
public struct ES3ReflectedMember
{
// The FieldInfo or PropertyInfo for this field.
private FieldInfo fieldInfo ;
private PropertyInfo propertyInfo ;
public bool isProperty ;
public bool IsNull { get { return fieldInfo = = null & & propertyInfo = = null ; } }
public string Name { get { return ( isProperty ? propertyInfo . Name : fieldInfo . Name ) ; } }
public Type MemberType { get { return ( isProperty ? propertyInfo . PropertyType : fieldInfo . FieldType ) ; } }
public bool IsPublic { get { return ( isProperty ? ( propertyInfo . GetGetMethod ( true ) . IsPublic & & propertyInfo . GetSetMethod ( true ) . IsPublic ) : fieldInfo . IsPublic ) ; } }
public bool IsProtected { get { return ( isProperty ? ( propertyInfo . GetGetMethod ( true ) . IsFamily ) : fieldInfo . IsFamily ) ; } }
public bool IsStatic { get { return ( isProperty ? ( propertyInfo . GetGetMethod ( true ) . IsStatic ) : fieldInfo . IsStatic ) ; } }
public ES3ReflectedMember ( System . Object fieldPropertyInfo )
{
if ( fieldPropertyInfo = = null )
{
this . propertyInfo = null ;
this . fieldInfo = null ;
isProperty = false ;
return ;
}
isProperty = ES3Reflection . IsAssignableFrom ( typeof ( PropertyInfo ) , fieldPropertyInfo . GetType ( ) ) ;
if ( isProperty )
{
this . propertyInfo = ( PropertyInfo ) fieldPropertyInfo ;
this . fieldInfo = null ;
}
else
{
this . fieldInfo = ( FieldInfo ) fieldPropertyInfo ;
this . propertyInfo = null ;
}
}
public void SetValue ( System . Object obj , System . Object value )
{
if ( isProperty )
propertyInfo . SetValue ( obj , value , null ) ;
else
fieldInfo . SetValue ( obj , value ) ;
}
public System . Object GetValue ( System . Object obj )
{
if ( isProperty )
return propertyInfo . GetValue ( obj , null ) ;
else
return fieldInfo . GetValue ( obj ) ;
}
}
public class ES3ReflectedMethod
{
private MethodInfo method ;
public ES3ReflectedMethod ( Type type , string methodName , Type [ ] genericParameters , Type [ ] parameterTypes )
{
MethodInfo nonGenericMethod = type . GetMethod ( methodName , parameterTypes ) ;
this . method = nonGenericMethod . MakeGenericMethod ( genericParameters ) ;
}
public ES3ReflectedMethod ( Type type , string methodName , Type [ ] genericParameters , Type [ ] parameterTypes , BindingFlags bindingAttr )
{
MethodInfo nonGenericMethod = type . GetMethod ( methodName , bindingAttr , null , parameterTypes , null ) ;
this . method = nonGenericMethod . MakeGenericMethod ( genericParameters ) ;
}
public object Invoke ( object obj , object [ ] parameters = null )
{
return method . Invoke ( obj , parameters ) ;
}
}
}
}