C#에서 참조 유형 변수에 "ref"를 사용하는 방법은 무엇입니까?
-
12-09-2019 - |
문제
값 유형(int
, struct
, 등)을 매개변수로 사용합니다( ref
키워드), 해당 변수의 복사본이 메서드에 전달되지만 ref
키워드에는 새 변수가 아닌 해당 변수에 대한 참조가 전달됩니다.
그러나 클래스와 같은 참조 유형을 사용하면 ref
키워드를 사용하면 복사본이 아닌 참조가 메서드에 전달됩니다.그렇다면 의 용도는 무엇입니까? ref
참조 유형이 있는 키워드는 무엇입니까?
예를 들면 다음과 같습니다.
var x = new Foo();
다음의 차이점은 무엇인가요?
void Bar(Foo y) {
y.Name = "2";
}
그리고
void Bar(ref Foo y) {
y.Name = "2";
}
해결책
당신은 무엇을 바꿀 수 있습니다 foo
사용 지점 y
:
Foo foo = new Foo("1");
void Bar(ref Foo y)
{
y = new Foo("2");
}
Bar(ref foo);
// foo.Name == "2"
다른 팁
실제를 수정하려는 경우가 있습니다. 참조 그리고 물체가 지적한 것이 아닙니다.
void Swap<T>(ref T x, ref T y) {
T t = x;
x = y;
y = t;
}
var test = new[] { "0", "1" };
Swap(ref test[0], ref test[1]);
존 스키트(Jon Skeet)가 썼다. 훌륭한 기사 C#의 매개변수 전달에 대해매개변수를 값, 참조로 전달하는 정확한 동작과 사용법을 명확하게 자세히 설명합니다(ref
) 및 출력별 (out
).
다음은 해당 페이지에서 다음과 관련된 중요한 인용문입니다. ref
매개변수:
참조 매개 변수는 에 사용된 변수의 값을 함수 멤버 호출 - 이들은 변수를 사용할 수 있습니다.오히려 새 저장 위치 만들기 함수 멤버의 변수 선언, 동일한 저장 위치 가 사용되므로 변수 함수의 멤버와 값 참조 매개 변수의 값은 항상 동일해야 합니다.참조 매개변수 필요 사항 의 일부로 참조 수정자를 선언과 호출 - 그 는 항상 명확하다는 것을 의미합니다 참조로 무언가를 전달합니다.
여기에 아주 잘 설명되었습니다.http://msdn.microsoft.com/en-us/library/s6938f28.aspx
기사에서 초록 :
기준 유형의 변수에는 데이터가 직접 포함되지 않습니다. 데이터에 대한 참조가 포함되어 있습니다. 참조 유형 매개 변수를 값별로 전달하면 클래스 멤버의 값과 같은 참조에 의해 지적 된 데이터를 변경할 수 있습니다. 그러나 참조 자체의 값을 변경할 수는 없습니다. 즉, 새로운 클래스에 메모리를 할당하기 위해 동일한 참조를 사용할 수없고 블록 외부에서 지속될 수 없습니다. 이렇게하려면 Ref 또는 Out Keyword를 사용하여 매개 변수를 전달하십시오.
Ref 키워드로 참조 유형을 전달하면 참조를 참조로 전달하고 호출하는 메소드는 매개 변수에 새 값을 할당 할 수 있습니다. 그 변화는 호출 범위로 전파 될 것입니다. REF가 없으면 참조는 가치로 전달되며 이런 일은 일어나지 않습니다.
C#은 또한 'ref'를 제외하고 'out'키워드를 가지고 있으며, 'ref'를 제외하고는 메소드를 호출하기 전에 인수를 초기화해야하며 'out'을 사용하려면 수신 방법에 값을 할당해야합니다.
전달 된 참조를 수정할 수 있습니다.
void Bar()
{
var y = new Foo();
Baz(ref y);
}
void Baz(ref Foo y)
{
y.Name = "2";
// Overwrite the reference
y = new Foo();
}
당신은 또한 사용할 수 있습니다 밖으로 전달 된 참조에 관심이없는 경우 :
void Bar()
{
var y = new Foo();
Baz(out y);
}
void Baz(out Foo y)
{
// Return a new reference
y = new Foo();
}
또 다른 코드
class O
{
public int prop = 0;
}
class Program
{
static void Main(string[] args)
{
O o1 = new O();
o1.prop = 1;
O o2 = new O();
o2.prop = 2;
o1modifier(o1);
o2modifier(ref o2);
Console.WriteLine("1 : " + o1.prop.ToString());
Console.WriteLine("2 : " + o2.prop.ToString());
Console.ReadLine();
}
static void o1modifier(O o)
{
o = new O();
o.prop = 3;
}
static void o2modifier(ref O o)
{
o = new O();
o.prop = 4;
}
}
기존 답변 외에도 :
두 가지 방법의 차이를 요청한대로 사용시 CO (NTRA) 분산이 없습니다. ref
또는 out
:
class Foo { }
class FooBar : Foo { }
static void Bar(Foo foo) { }
static void Bar(ref Foo foo) { foo = new Foo(); }
void Main()
{
Foo foo = null;
Bar(foo); // OK
Bar(ref foo); // OK
FooBar fooBar = null;
Bar(fooBar); // OK (covariance)
Bar(ref fooBar); // compile time error
}
메소드의 매개 변수는 항상 사본을 전달하는 것 같습니다. 질문은 무엇의 사본입니다. 사본은 객체에 대한 사본 생성자에 의해 수행되며 모든 변수는 C#의 객체이므로 모든 변수가 모든 변수라고 생각합니다. 변수 (물체)는 일부 주소에 사는 사람들과 같습니다. 우리는 그 주소에 사는 사람들을 바꾸거나 전화 번호부의 주소에 사는 사람들에 대한 더 많은 언급을 만들 수 있습니다 (얕은 사본 만들기). 따라서 둘 이상의 식별자가 동일한 주소를 참조 할 수 있습니다. 참조 유형은 더 많은 공간을 원하므로 스택의 식별자에 화살표로 직접 연결되는 값 유형과 달리 힙의 다른 주소 (거주 할 공간)에 대한 가치가 있습니다. 이 공간은 힙에서 가져와야합니다.
값 유형 : Innentifier (값 포함 = 스택 값 주소) ----> 값 유형의 가치 유형
참조 유형 : 식별자 (값 포함 = 스택 값 주소 포함) ----> (값 = 힙 값의 주소 포함) ----> 힙 값 (대부분 다른 값에 대한 주소를 포함 함), 더 많은 화살표가 다른 화살표를 상상해보십시오. 배열 방향 [0], 배열 [1], 배열 [2
값을 변경하는 유일한 방법은 화살표를 따르는 것입니다. 한 화살표가 값을 도달 할 수없는 방식으로 분실/변경하면.
참조 변수는 한 장소에서 다른 장소로 주소를 전달하므로 어떤 장소에서든 업데이트되면 모든 장소에 반영되며 REF의 용도는 무엇입니까?참조 변수(405)는 메서드에 전달된 참조 변수에 새 메모리가 할당되지 않을 때까지 유효합니다.
새로운 메모리가 할당되면(410) 이 객체(408)의 값 변경은 모든 곳에 반영되지 않습니다.이 심판이 온다.Ref는 참조 참조이므로 새 메모리가 할당될 때마다 해당 위치를 가리키므로 이를 알게 되므로 모든 사람이 값을 공유할 수 있습니다.더 명확하게 이미지를 볼 수 있습니다.