Skip to content

Instantly share code, notes, and snippets.

@pardeike
Created January 2, 2020 15:07
Show Gist options
  • Save pardeike/9f68fd3f05a04c2081c1b506a0ff9796 to your computer and use it in GitHub Desktop.
Save pardeike/9f68fd3f05a04c2081c1b506a0ff9796 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
public class Program
{
// simulating a Harmony Passthrough Postfix
// (run it here: https://dotnetfiddle.net/qMPu6m)
//
// A passthrough postfix can be used to execute code between yields
// of an enumerator method. Normally, you cannot patch those methods
// because the compiler turns them into hidden state machine classes
// and patching the original method will just influence the small stub
// method that creates an instance of that compiler generated class
//
// This example will visualize how you can use the fact that enumerators
// are in fact "generator functions" that get their results "pulled" out
// of them one-by-one instead of running like normal methods.
//
// Harmony uses this to wrap the original with the enumerator that is
// generated when you create a PASSTHROUGH POSTFIX:
// --------------------------------------------------------
// static T Postfix(T varname, ...normal postfix arguments)
// --------------------------------------------------------
// This works for any T but is especially useful for T = IEnumerator
public static void Main()
{
Console.WriteLine("\n# Original");
var it1 = Original();
while(it1.MoveNext())
Console.WriteLine(it1.Current);
Console.WriteLine("\n# With Passthrough Postfix)");
var it2 = Postfix(Original());
while(it2.MoveNext())
Console.WriteLine(it2.Current);
}
static IEnumerator Original()
{
Console.WriteLine("Apple");
yield return 10;
Console.WriteLine("Banana");
yield return 20;
Console.WriteLine("Cherry");
yield return 30;
Console.WriteLine("Melon");
yield return 40;
}
static IEnumerator Postfix(IEnumerator e)
{
var n = 0;
while(e.MoveNext())
{
var element = e.Current;
if (n == 2)
Console.WriteLine("[PRE]");
yield return element;
if (n == 2)
Console.WriteLine("[POST]");
n += 1;
}
}
}
// # Original
// Apple
// 10
// Banana
// 20
// Cherry
// 30
// Melon
// 40
//
// # With Passthrough Postfix)
// Apple
// 10
// Banana
// 20
// Cherry
// [PRE]
// 30
// [POST]
// Melon
// 40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment