C#에서는 ref를 사용하여 참조로 클래스 필드에 값을 할당하는 것처럼 보일 수 있습니다. 매개변수 수정자. 그러나 이 기술은 필드에 할당할 때 참조를 유지하지 못합니다.
다음 코드 조각을 고려하세요.
public class X { public X() { string example = "X"; new Y(ref example); new Z(ref example); System.Diagnostics.Debug.WriteLine(example); } } public class Y { public Y(ref string example) { example += " (Updated By Y)"; } } public class Z { private string _Example; public Z(ref string example) { this._Example = example; this._Example += " (Updated By Z)"; } } var x = new X();
예상되는 출력은 다음과 같습니다. 두 업데이트 모두 "X (Updated By Y) (Updated By Z)" 문자열에 적용되지만 실제 출력은 "X (Updated By Y)"뿐입니다. 이는 필드에 할당할 때 참조를 어떻게 유지해야 하는지에 대한 의문을 제기합니다.
제한 사항은 C#이 ref 유형의 필드를 허용하지 않는다는 사실에서 비롯됩니다. 이 제약 조건은 참조 필드를 완전히 허용하지 않거나 잠재적으로 충돌을 일으킬 수 있는 안전하지 않은 필드를 허용하는 것 중에서 선택하도록 강제합니다. 또한 로컬 변수(스택)에 대한 임시 저장소 풀을 사용하면 메서드가 완료된 후 더 이상 존재하지 않을 수 있는 값에 액세스하는 것과 충돌할 수 있습니다.
이러한 문제를 방지하기 위해 C#에서는 참조 필드를 금지하고 사용을 권장합니다. getter 및 setter 메서드 대신:
sealed class Ref<T> { private readonly Func<T> getter; private readonly Action<T> setter; public Ref(Func<T> getter, Action<T> setter) { this.getter = getter; this.setter = setter; } public T Value { get { return getter(); } set { setter(value); } } } ... Ref<int> x; void M() { int y = 123; x = new Ref<int>(() => y, z => { y = z; }); x.Value = 456; Console.WriteLine(y); // 456 -- setting x.Value changes y. }
이 접근 방식을 사용하면 x 효과적으로 y가 가비지 수집 힙에 저장되어 있어도 y 값을 가져오고 설정할 수 있는 개체가 됩니다.
C#은 직접적으로 그렇지 않습니다. ref 반환 메서드 및 ref 매개 변수를 지원합니다. 이 기능은 C# 7에서 구현되었습니다. 그러나 ref 유형을 필드로 사용할 수 없다는 제한 사항은 여전히 남아 있습니다.
위 내용은 C#에서 참조 작업을 통해 클래스 필드에 값을 전달하지 못하는 이유는 무엇이며 유사한 동작을 달성하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!