리플렉션을 써보신 분들이라면 MethodInfo.Invoke가 느리다는데에 동감하실 겁니다.

그래서 lcg로 메소드를 Func<object, object[], object>타입으로 래핑하려고 합니다.

첫 인자로 this, 두번째 인자로 매개변수들이 들어가는 형식입니다.



class Boo
{
    public Boo Foo(Boo arg);
}
예를 들어 위와 같은 함수가 있으면,

ldarg.0
castclass Boo
ldarg.1
ldc.i4.0
ldelem.ref
castclass Boo
callvirt Boo::Foo(Boo)
ret
위와 같은 msil이 생성되는 식입니다.



그런데, this로 넘겨주어야할 타입이 참조형식일땐 괜찮았지만, 값형식일때 문제가 생깁니다.

struct Boo
{
    public Boo Foo(Boo arg);
}
위와 같은 함수가 있으면,

ldarga.s 0
ldarg.1
ldc.i4.0
ldelem.ref
unbox.any Boo
callvirt Boo::Foo(Boo)
box Boo
ret
위와 같은 msil이 생성되는데

첫 인자로 this를 넘겨줄때 깊은복사가 일어나 아래와 같은 코드에서 비정상적으로 동작합니다.

struct Boo
{
    private int _a;

    public Boo Foo(Boo arg)
    {
        _a = arg._a;
        return this;
    }
}

원래는 다음대로 작동해야 할 것이
1. this가 앝은 복사가되어 첫 인자로 들어감
2. 첫 인자로 참조된 Boo의 _a가 수정됨
3. 반환된 Boo의 _a와 원래의 Boo의 _a가 같음

다음대로 작동하게 됩니다
1. 원래의 this가 깊은복사가 되어 첫번째 인자로 들어감
2. 첫번째 인자로 복사된 Boo의 _a가 수정됨
3. 반환된 Boo의 _a와 원래의 Boo의 _a의 값이 달라짐



ldarg.s 0를 다른 구문으로 고쳐야 할것 같은데, 제 머리로는 도저히 모르겠습니다.

<1줄 요약>
혹시 ref키워드나 TypedRefernece, c++/cil없이 값형식을 메서드에 참조로 넘기는 법을 아시는 분은 알려주시면 감사하겠습니다.



옛날에 찾았던 이슈라 아래 github링크에도 올려두었습니다.
전체 코드가 궁금하신 분들은 참고해 주세요!

https://github.com/Sharp0802/DynamicInvoker/issues/3