메소드 내부에서 박스형 값 유형을 수정하는 방법
-
08-07-2019 - |
문제
C#에서 늦은 바인딩 호출을 단순화하기 위해 라이브러리를 구축하려고합니다. 참조 매개 변수로 트링하는 데 어려움을 겪고 있습니다. 메소드 호출에 사용 된 매개 변수를 추가하는 방법이 있습니다.
public IInvoker AddParameter(ref object value)
{
//List<object> _parameters = new List<object>();
_parameters.Add(value);
//List<bool> _isRef = new List<bool>();
_isRef.Add(true);
return this;
}
그리고 그것은 값 유형과 함께 작동하지 않습니다. 왜냐하면 그들은 객체로 상자를 가져 오기 때문에 수정되지 않습니다. 예 :
int param1 = 2;
object paramObj = param1;
//MulFiveRef method multiplies the integer passed as a reference parameter by 5:
//void MulFiveRef(ref int value) { value *= 5; }
fi.Method("MulFiveRef").AddParameter(ref paramObj);
그것은 작동하지 않습니다. 늦은 바인딩 호출은 성공적이며 매개 변수 (_parameters)를 보유하는 내부 목록은 수정되지만 통화 외부의 값은 수정되지 않습니다.
이 제한을 극복하는 간단한 방법을 알고 있습니까? AddParameter 서명을 수정할 수 없습니다. 늦은 바인딩 호출과 마찬가지로 매개 변수의 유형을 미리 알 수 없습니다 (및 호출을 작성하기 전에 객체 배열 내부의 모든 매개 변수를 삽입하는 방법).
미리 감사드립니다.
해결책
값이 바뀌는 경우 방법 내부, 당신은 온도를 선언해야합니다 (object
) 변수 통과 (ref
) 방법에 대해, 나중에 직접 박스를 unbox :
int i = 3;
//...
object obj = i;
Foo(ref obj);
i = (int)obj;
이를 통해 이벤트 후 값을 업데이트 할 수 없습니다. 이벤트 나 콜백과 같은 것은 발신자에게 변경 사항을 다시 전달하는 대안적인 방법 일 수 있습니다.
C# 4.0에는 이에 도움이되는 몇 가지 트릭이 있습니다. 뿐 COM 호출의 맥락에서 (여기서 ref object
매우 일반적입니다 [물론 dynamic
Jon Notes와 같이 늦은 바인딩의 경우)).
다른 팁
당신의 방법은 변하지 않습니다 value
어쨌든 - 왜 참조로 전달합니까? 의미가 있지만 실제로는 명확하지 않습니다. 제공 한 샘플 코드는 어쨌든 컴파일되지 않습니다. ref
논쟁이 있어야합니다 바로 그거죠 매개 변수와 동일한 유형입니다.
(또한 C# 4.0 및 .NET 4.0은 늦은 바인딩에 대한 내장 지원을받을 것임을 알고 있습니까? 언어 통합 버전이 라이브러리 전용 버전보다 사용하기가 더 쉬울 가능성이 있습니다. 이 시점에서 도서관에서 시간?)
편집 : 제공 한 코드는 실제로 컴파일되지 않습니다. 당신은 권투를받지 못합니다 ref
인수와 매개 변수 유형이 정확히 동일해야하기 때문에 매개 변수는 정확히 동일해야합니다. 다음은이를 증명하기위한 샘플 코드입니다.
public class Test
{
static void Main()
{
int i;
Foo(ref i); // Won't compile - error CS1502/1503
}
static void Foo(ref object x)
{
}
}
현재 코드 인 경우 ~이다 컴파일하면 질문에서 제시 한 코드가 아닙니다. 아마도 당신은 또 다른 과부하가있을 것입니다 AddParameter
수락합니다 ref int
?
자, Jon Skeet Corrections와 Mark Gravell 코드 덕분 에이 인터페이스를 생각해 냈습니다.
//This will be created with a factory
IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>());
int param1 = 2;
object paramObj = param1;
invoker.AddParameter(ref paramObj).Invoke("MulFiveRef");
param1 = (int)invoker.Parameters[0];
내가 상상했던 것과 정확히는 아니지만 이전 인터페이스보다 더 간단하고 읽을 수 있습니다.
IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>());
int refValue = 10;
object[] args = Args.Build(refValue);
invoker.Call("MulFiveRef", Args.ByRefIndexs(0), args);
refValue = (int)args[0];
도움을 주셔서 대단히 감사합니다 :)