아래 예제 코드가 있습니다.
“test” 문자열로 초기화한 지역변수
a, sb, b 3개가 있는데요
아래 코드를 실행했을 때 할당되는 값은 아래와 같습니다.
a → “test”
sb → {test/add}
b → “test/add”
a만 문자열이 변경되지 않고 그대로 있습니다.
a와 b의 차이점은 투명 프록시 인스턴스를 사용했냐 안했냐의 차이 같은데
-
투명 프록시 인스턴스를 사용하면 무엇 때문에 이렇게 동작하는 지 궁금합니다.
-
같은 투명 프록시 인스턴스를 사용했음에도 StringBuilder 객체는 값이 변경되었습니다. 클래스 객체라서 call by reference로 동작하는 건 알지만 string을 ref로 하는 것과 무슨 차이가 있는 건지 궁금합니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Text;
using System.Threading.Tasks;
namespace InvokeTest
{
public class TraceProxy : RealProxy
{
private readonly T _decorated;
public TraceProxy(T decorated)
: base(typeof(T))
{
_decorated = decorated;
}
public override IMessage Invoke(IMessage msg)
{
var methodCall = msg as IMethodCallMessage;
var methodInfo = methodCall?.MethodBase as MethodInfo;
try
{
var result = methodInfo?.Invoke(_decorated, methodCall.InArgs);
return new ReturnMessage(result, null, 0, methodCall?.LogicalCallContext, methodCall);
}
catch (Exception e)
{
return new ReturnMessage(e, methodCall);
}
}
}
public class Test : MarshalByRefObject
{
public void RefTest(ref string a)
{
a += "/add";
}
public void SBTest(StringBuilder sb)
{
sb.Append("/add");
}
}
public class Proxy
{
public static T Create<T>(T instance)
{
var dynamicProxy = new TraceProxy<T>(instance);
return (T)dynamicProxy.GetTransparentProxy();
}
}
class Program
{
static void Main(string[] args)
{
var t = Proxy.Create<Test>(new Test());
string a = "test";
string b = "test";
StringBuilder sb = new StringBuilder("test");
t.RefTest(ref a);
t.SBTest(sb);
Test t2 = new Test();
t2.RefTest(ref b)
;
}
}
}