Skip to content

Instantly share code, notes, and snippets.

@peteroupc
Last active December 12, 2015 01:28
Show Gist options
  • Save peteroupc/4691115 to your computer and use it in GitHub Desktop.
Save peteroupc/4691115 to your computer and use it in GitHub Desktop.
Reflection utility methods
// 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