Is it possible to use reflection to replace a methods'behaviour to "Do Nothing"

Is it possible to use reflection to replace a methods’behaviour to “Do Nothing”

I strongly advise you to share what is your real goal you want to achieve instead of the reflection madness. Most of the time you can achieve said behavior more simply without abysmal performance (reflection) and erratic architecture (also changes through reflection).
So what is it you want to achieve with this exactly?

2 Likes

Yes.

As @ pointed out, the more pertinent question is “why”?

I’m calling a function A in someone else’s code, the function A will call function B, now I want function B to do nothing, although modifying his code directly or writing another A that does not call B can solve the problem simply ,But I prefer not to modify other people’s code or write duplicate code

How to do?

Use reflection.

Who wrote function B?

Why not just make a small change to Method A. Add a bool which is set to true and then you can just add that bool when you call it from your code. That won’t affect how that method works for anything else.

        public void MethodA(bool runMethodB = true)
        {
            if (runMethodB)
            {
                MethodB();
            }
        }

        public void MethodB()
        {

        }

Both function A and function B are private and in the same class. This script I downloaded from the Internet

It’s better not to change the code

If you have access to the source, you can easily override method A to add the check to run B or not.

I don’t see a way to change the behaviour of A and B without some kind of extending or overriding - and I don’t know why you would use reflection for either. Reflection will tell you metadata about the class, not allow you to change the flow of control nor which method was used to invoke you. The latter can be done using Szstem.Diagnostics though.

Thanks, I solved the problem with 0harmony.dll after a long time in Google, it can perfectly replace one function with another function, that is what I want

You may run into issues when deploying to platforms that rely on IL2CPP and other AOT type compilation like apple, consoles, etc.

Furthermore, this is a very hack fix to an otherwise easy to fix problem. By replacing the function that means that function is no longer there. Never, not when you call Function A, and not when ANY OTHER CODE calls Function A or Function B. That functionality is now gone. You deleted it at runtime.

I’m not sure why you’re adverse to editing the “other people’s” code if you have the source in hand. You have the source code in your program… edit it. Editing at runtime is effectively the same thing. You’ve edited it! Any adverse effects are going to be there regardless of when you edited it (before compile, or after compile).

The only reason I could argue to go the route you’re going is if you don’t have access to the source. Such as you integrated a 3rd party dll or something and you can’t actually modify the code. But even then… I find this bonkers, there are so many better ways to go about this (though picking the best one would require my knowing your situation… I honestly don’t even know in which sense you have access to this code).

Yet you’ve changed it.

You’ve changed it in a more complicated round about way meaning testing is going to be a headache now.

Maybe that is what you want, but it may not what you actually need.

I just found out that I was wrong. I injected my function into function B. The original code of function B is still being executed. I found a real replacement solution, but it is too complicated. Perhaps copying and modifying is the best way.

I used to like to directly modify other people’s code, even if I didn’t fully understand it. After a period of time, original author submitt updates and fix some bugs. Merging the updates became a big problem, so I’m a little scared to change othter people’s code. now it seems that there is no choice

There’s ways to mitigate the amount of changes needed.

For example you can inherit from it and create a overloaded method in the inherited class.

If inheritance isn’t an option just because you don’t want to have to remember to use the inherited version. You can turn it into a partial class (a single keyword in the existing code), add the 2nd part of the partial class to its own code file along side, add your overloaded method there, and then when you go and update it all you need to do is remember to keep the “partial” keyword in the updated version.

No matter what, any class I’ve modified I always put a big note section at the top of the class with my own special keywords and explain what I’ve changed. Something like:

/*
 * LOD UPGRADE - changed class to be partial to allow overloading MethodA.
 *     See SomeClassIChanged.Overload.cs for the added functionality.
 */
using UnityEngine;

public partial class SomeClassIChanged : MonoBehaviour
{

    public void MethodA() //the original method
    {
        this.transform.position = Vector3.zero; //do arbitrary MethodA stuff

        MethodB();
    }
...

Then in my partial:

public partial class SomeClassIChanged : MonoBehaviour
{

    public void MethodAWithoutCallingMethodB()
    {
        //copy contents of MethodA here, but leave out the call to MethodB
        this.transform.position = Vector3.zero; //do arbitary MethodA stuff
    }

}

For more information on partial classes:

Heck… depending on what MethodA does… if it doesn’t access any private members (aside from MethodB which we don’t want to call anyways). You could just create your overload as an “extension method”. No need for a partial class at all.: