Title: Replace Property-Setter Method Ptr
Tags: c#;pointers;replace;setter;methodinfo
Question: ```public delegate void SetProp(object obj);

void Main()
{
    TestObj obj = new TestObj();

    SetProp setPropDel = (SetProp)SetProp.CreateDelegate(typeof(SetProp), 
    obj, obj.GetSetPropDelegate().GetMethodInfo());
    MethodInfo setPropMethod = setPropDel.GetMethodInfo();

    ///Replacing Count Set-Method Pointer with new Method
    typeof(TestObj).GetProperty("Count").GetSetMethod().ReplaceMethodPtr(setPropMethod);
    obj.Count = 1;
```

}

```public class TestObj
{
    public SetProp GetSetPropDelegate() =&gt; SetPropValue;

    private void SetPropValue(object obj) =&gt; Console.WriteLine(obj); ///<--- NullReferenceException obj is null.

    public int Count { get; set; }
```

}

Hi, I was trying to replace the private set-Method for the auto-Property "Count" in my class TestObj.

The replacement itself works. Because when I use the setter like 'obj.Count = 1' the new method is being called.

My question is: Is it possible to pass a parameter into this new method?
I'd at least need the new value that is being allocated to the Count-Property. In this case: 1.

My goal is to make it possible to replace Set-Methods of automatic properties to raise an event, when the new Set-Method is being called, and also keep basic function of the Set-Method.

I hope it's clear what I want to achieve. I might've run into something impossible here, but I'm sure there are lots of people have a much better understand of what's going on.

Thanks for reading.



Here is another answer: I want to share how I solved this problem.

I wrote a whole library with more functionalities, like events that are being raised on set or get occasions. But for the answer I want to break it down into the simplest example.

```void Main()
{
    MethodInfo targetMethod = typeof(TargetObj).GetProperty("Count").GetSetMethod();
    MethodInfo injectMethod = typeof(InjectObj).GetMethod("SetCount");

    targetMethod.InjectMethod(injectMethod);

    var targetInstance = new TargetObj();

    targetInstance.Count = 3;
}

public class TargetObj
{
    public int Count { get; set; }
}

public class InjectObj
{
    public void SetCount(int value)
    {
        GetBackingField(this, "Count").SetValue(this, value);
        Console.WriteLine($"Count has been set to [{value}]");
    }
}

public static FieldInfo GetBackingField(object obj, string propertyName) =&gt; obj.GetType().GetField($"<{propertyName}&gt;k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
```

If this code is run, the console-output is:
    Count has been set to [3]

The possibilities using this approach are endless but I wanted to give a quick look in how I managed to achieve this.

Note that I did this example using Linqpad.

I don't want to lengthen the post unnecassarily, but I need to include the MethodInfo Extension Method "InjectMethod" for a full understanding of what is going on.

```public static class MethodInfoExtensions
{
    public static void InjectMethod(this MethodInfo target, MethodInfo inject)
    {
        RuntimeHelpers.PrepareMethod(inject.MethodHandle);
        RuntimeHelpers.PrepareMethod(target.MethodHandle);

        unsafe
        {
            if (IntPtr.Size == 4)
            {
                int* inj = (int*)inject.MethodHandle.Value.ToPointer() + 2;
                int* tar = (int*)target.MethodHandle.Value.ToPointer() + 2;

                if (Debugger.IsAttached)
                {
                    byte* injInst = (byte*)*inj;
                    byte* tarInst = (byte*)*tar;

                    int* injSrc = (int*)(injInst + 1);
                    int* tarSrc = (int*)(tarInst + 1);

                    *tarSrc = (((int)injInst + 5) + *injSrc) - ((int)tarInst + 5);
                }
                else
                {
                    *tar = *inj;
                }
            }
            else
            {
                long* inj = (long*)inject.MethodHandle.Value.ToPointer() + 1;
                long* tar = (long*)target.MethodHandle.Value.ToPointer() + 1;

                if (Debugger.IsAttached)
                {
                    byte* injInst = (byte*)*inj;
                    byte* tarInst = (byte*)*tar;

                    int* injSrc = (int*)(injInst + 1);
                    int* tarSrc = (int*)(tarInst + 1);

                    *tarSrc = (((int)injInst + 5) + *injSrc) - ((int)tarInst + 5);
                }
                else
                {
                    *tar = *inj;
                }
            }
        }
    }
}
```

Using this kind of method-replacement I'd recommend only for test-purposes or maybe as a sort of debug-tool.
I'm pretty sure implementing this into a real releasing software would generate more problems than it solves.


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2018:00:09/05/18', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<c#><pointers><replace><setter><methodinfo>', 'Title': 'Replace Property-Setter Method Ptr', 'ViewCount': 294, 'id': 52179498, 'user_AboutMe': None, 'user_AccountId': 13472162.0, 'user_DisplayName': 'Jiji', 'user_Reputation': 79.0, 'user_Views': 11.0, 'user_id': 9720306.0}}