Skip to content

Utilities

Andreas Pardeike edited this page Mar 25, 2017 · 11 revisions

AccessTools

To simplify reflections, Harmony has a helper class called AccessTools. Here are the most commonly used methods:

public static BindingFlags all = ....
public static Type TypeByName(string name)
public static FieldInfo Field(Type type, string name)
public static PropertyInfo Property(Type type, string name)
public static MethodInfo Method(Type type, string name, Type[] parameters = null, Type[] generics = null)
public static ConstructorInfo Constructor(Type type, Type[] parameters = null)
public static Type Inner(Type type, string name)
public static Type FirstInner(Type type, Func<Type, bool> predicate)

Any of these methods use the all BindingFlags definition and thus work on anything regardless if it is public, private, static or else.

Traverse

In order to access fields, properties and methods from classes via reflection, Harmony contains a utility called Traverse. Think of it as LINQ for classes.

Example:

class Foo
{
	struct Bar
	{
		static string secret = "hello";

		public string ModifiedSecret()
		{
			return secret.ToUpper();
		}
	}

	Bar myBar
	{
		get
		{
			return new Bar();
		}
	}

	public string GetSecret()
	{
		return myBar.ModifiedSecret();
	}

	Foo()
	{
	}

	static Foo MakeFoo()
	{
		return new Foo();
	}
}

var foo = Traverse.Create<Foo>().Method("MakeFoo").GetValue<Foo>();
Traverse.Create(foo).Property("myBar").Field("secret").SetValue("world");
Console.WriteLine(foo.GetSecret()); // outputs WORLD

Although most fields, properties and methods in that class hierarchy are private, Traverse can easily access anything. It has build-in null protection and propagates null as a result if any of the intermediates would encounter null. It works with static types and caches lookups which makes it pretty fast.

Clone this wiki locally