Как выполнить исправление метода среды выполнения .NET для статического неуниверсального метода универсального класса? (Гармония или МоноМод)

В этом примере я хочу исправитьPatchTarget.QSingleton\<T\>.get_Instance().
Как это сделать с помощью Harmony или MonoMod?

Гармония:

«Необработанное исключение. System.NotSupportedException: указанный метод не поддерживается».

Мономод:

«Необработанное исключение. System.ArgumentException: данный общий экземпляр был недопустимым».

Фрагмент кода: (запускается сdotnetfiddle.net)

      using System; 
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using HarmonyLib;

namespace PatchTarget {
  public abstract class QSingleton<T> where T : QSingleton<T>, new() {
    protected static T instance = null; protected QSingleton() { } 

    public static T Instance { get {
      if (instance == null) {
        instance = new T();
        Console.Write($"{typeof(T).Name}.Instance: impl=QSingleton");
      }
      return instance; 
    } }
  } 
}

namespace Patch {
  public class TypeHelper<T> where T : PatchTarget.QSingleton<T>, new() {
    public static T InstanceHack() {
      Console.Write($"{typeof(T).Name}.Instance: impl=InstanceHack");
      return null;
    }
  }
    
  public static class HarmonyPatch {
    public static Harmony harmony = new Harmony("Try");

    public static void init() {
      var miOriginal = AccessTools.Property(typeof(PatchTarget.QSingleton<>), "Instance").GetMethod;
      var miHack = AccessTools.Method(typeof(TypeHelper<>), "InstanceHack");
      harmony.Patch(miOriginal, prefix: new HarmonyMethod(miHack));
    }
  }

  public static class MonoModPatch {
    public static MonoMod.RuntimeDetour.Detour sHook;

    public static void init() {
      var miOriginal = AccessTools.Property(typeof(PatchTarget.QSingleton<>), "Instance").GetMethod;
      var miHack = AccessTools.Method(typeof(TypeHelper<>), "InstanceHack");
      sHook = new MonoMod.RuntimeDetour.Detour(miOriginal, miHack);
    }
  }
}

class Program {
  public static void Main() {
    Patch.HarmonyPatch.init();
    // Patch.MonoModPatch.init();
    Console.WriteLine($"done");
  }
}

0 ответов

Другие вопросы по тегам