Last active
December 12, 2015 01:28
-
-
Save peteroupc/4691115 to your computer and use it in GitHub Desktop.
Reflection utility methods
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This file is in the public domain. Peter O., 2013. http://upokecenter.dreamhosters.com | |
// Public domain dedication: http://creativecommons.org/publicdomain/zero/1.0/ | |
using System; | |
using System.Reflection; | |
namespace PeterO | |
{ | |
public static class ReflectionUtil { | |
private static MethodInfo GetStaticMethod(Type clazz, String name, int argCount){ | |
if(clazz==null)return null; | |
MethodInfo con=null; | |
foreach(MethodInfo c in clazz.GetMethods()){ | |
int paramLength=c.GetParameters().Length; | |
if((paramLength==argCount || (c.CallingConvention==CallingConventions.VarArgs && paramLength>=argCount+1)) && | |
c.Name.Equals(name)){ | |
if(con==null) | |
con=c; | |
else | |
return null; // ambiguous | |
} | |
} | |
return con; | |
} | |
public static MethodInfo GetStaticMethod(Type clazz, String name){ | |
if(clazz==null)return null; | |
MethodInfo con=null; | |
foreach(MethodInfo c in clazz.GetMethods()){ | |
if(c.Name.Equals(name)){ | |
if(con==null) | |
con=c; | |
else | |
return null; // ambiguous | |
} | |
} | |
return con; | |
} | |
public static MethodInfo GetMethod(Object obj, String name){ | |
return GetStaticMethod(obj.GetType(),name); | |
} | |
public static FieldInfo GetStaticFieldInfo(Type clazz, String name){ | |
if(clazz==null)return null; | |
return clazz.GetField(name); | |
} | |
public static FieldInfo GetFieldInfo(Object obj, String name){ | |
return GetStaticFieldInfo(obj.GetType(),name); | |
} | |
public static bool GetFieldWithTest( | |
Object obj, FieldInfo field, Object[] retvalue){ | |
if(retvalue!=null && retvalue.Length>0){ | |
retvalue[0]=null; | |
} | |
if(field==null){ | |
return false; | |
} | |
try { | |
Object ret=field.GetValue(obj); | |
if(retvalue!=null && retvalue.Length>0){ | |
retvalue[0]=ret; | |
} | |
return true; | |
} catch (ArgumentException e) { | |
return false; | |
} catch (FieldAccessException e) { | |
return false; | |
} | |
} | |
public static Object GetFieldByName( | |
Object obj, String name, Object defaultValue){ | |
return GetField(obj,GetStaticFieldInfo(obj.GetType(),name),defaultValue); | |
} | |
public static bool GetStaticFieldByNameWithTest( | |
String className, String name, Object[] retvalue){ | |
return GetFieldWithTest(null,GetStaticFieldInfo(GetClassForName(className),name),retvalue); | |
} | |
public static Object GetStaticFieldByName( | |
String className, String name, Object defaultValue){ | |
return GetField(null,GetStaticFieldInfo(GetClassForName(className),name),defaultValue); | |
} | |
public static Object GetStaticFieldByName( | |
Type clazz, String name, Object defaultValue){ | |
return GetField(null,GetStaticFieldInfo(clazz,name),defaultValue); | |
} | |
public static bool GetFieldByNameWithTest( | |
Object obj, String name, Object[] retvalue){ | |
return GetFieldWithTest(obj,GetStaticFieldInfo(obj.GetType(),name),retvalue); | |
} | |
public static bool GetStaticFieldByNameWithTest( | |
Type clazz, String name, Object[] retvalue){ | |
return GetFieldWithTest(null,GetStaticFieldInfo(clazz,name),retvalue); | |
} | |
public static Object GetField(Object obj, FieldInfo method, Object defaultValue){ | |
Object[] ret=new Object[]{defaultValue}; | |
if(!GetFieldWithTest(obj,method,ret)){ | |
return defaultValue; | |
} | |
return ret[0]; | |
} | |
public static MethodInfo GetStaticMethodWithTypes(Type clazz, String name, params Type[] types){ | |
if(clazz==null)return null; | |
return clazz.GetMethod(name,types); | |
} | |
public static MethodInfo GetMethodWithTypes(Object obj, String name, params Type[] types){ | |
return GetStaticMethodWithTypes(obj.GetType(),name,types); | |
} | |
public static bool InvokeWithTest( | |
Object obj, MethodInfo method, | |
Object[] retvalue, params Object[] args){ | |
if(retvalue!=null && retvalue.Length>0){ | |
retvalue[0]=null; | |
} | |
if(method==null){ | |
return false; | |
} | |
try { | |
Object ret=method.Invoke(obj,args); | |
if(retvalue!=null && retvalue.Length>0){ | |
retvalue[0]=ret; | |
} | |
return true; | |
} catch (ArgumentException e) { | |
return false; | |
} catch (MethodAccessException e) { | |
return false; | |
} catch (TargetInvocationException e) { | |
throw e.InnerException; | |
} | |
} | |
public static bool InvokeStaticByNameWithTest( | |
Type clazz, String name, | |
Object[] retvalue, params Object[]args){ | |
return InvokeWithTest(clazz,GetStaticMethod(clazz,name,args.Length),retvalue,args); | |
} | |
public static bool InvokeByNameWithTest( | |
Object obj, String name, | |
Object[] retvalue, params Object[]args){ | |
return InvokeWithTest(obj,GetStaticMethod(obj.GetType(),name,args.Length),retvalue,args); | |
} | |
public static Object InvokeByName( | |
Object obj, String name, Object defaultValue, params Object[]args){ | |
return Invoke(obj,GetStaticMethod(obj.GetType(),name,args.Length),defaultValue,args); | |
} | |
public static Object InvokeStaticByName( | |
Type clazz, String name, Object defaultValue, params Object[]args){ | |
return Invoke(null,GetStaticMethod(clazz,name,args.Length),defaultValue,args); | |
} | |
public static Object Invoke(Object obj, MethodInfo method, Object defaultValue, params Object[]args){ | |
Object[] ret=new Object[]{defaultValue}; | |
if(!InvokeWithTest(obj,method,ret,args)){ | |
return defaultValue; | |
} | |
return ret[0]; | |
} | |
private static Object NewInstance(ConstructorInfo con, params Object[]args){ | |
if(con==null)return null; | |
try { | |
return con.Invoke(args); | |
} catch (ArgumentException e) { | |
return null; | |
} catch (MemberAccessException e) { | |
return null; | |
} catch (TargetParameterCountException e) { | |
return null; | |
} catch (TargetInvocationException e) { | |
throw e.InnerException; | |
} | |
} | |
public static Type GetClassForName(String name){ | |
return Type.GetType(name); | |
} | |
public static Object ConstructWithTypes(Type clazz, Type[] parameterTypes, params Object[] args){ | |
if(parameterTypes.Length!=args.Length) | |
throw new ArgumentException(); | |
if(clazz==null)return null; | |
ConstructorInfo con=clazz.GetConstructor(parameterTypes); | |
return NewInstance(con,args); | |
} | |
public static Object Construct(String className, params Object[] args){ | |
return Construct(GetClassForName(className),args); | |
} | |
public static Object ConstructWithTypes(String className,Type[] parameterTypes, params Object[] args){ | |
return ConstructWithTypes(GetClassForName(className),parameterTypes,args); | |
} | |
public static Object Construct(Type clazz, params Object[] args){ | |
ConstructorInfo con=null; | |
if(clazz==null)return null; | |
foreach(ConstructorInfo c in clazz.GetConstructors()){ | |
int paramLength=c.GetParameters().Length; | |
if((paramLength==args.Length || (c.CallingConvention==CallingConventions.VarArgs && paramLength>=args.Length+1))){ | |
if(con==null) | |
con=c; | |
else | |
return null; // ambiguous | |
} | |
} | |
return NewInstance(con,args); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment