객체를 전달할 때 'ref' 키워드를 사용하는 이유는 무엇입니까?
개체를 메서드에 전달하는 경우 ref 키워드를 사용해야 하는 이유는 무엇입니까?어쨌든 이것이 기본 행동이 아닌가요?
예:
class Program
{
static void Main(string[] args)
{
TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(t);
Console.WriteLine(t.Something);
}
static public void DoSomething(TestRef t)
{
t.Something = "Bar";
}
}
public class TestRef
{
public string Something { get; set; }
}
출력은 "Bar"이며, 이는 객체가 참조로 전달되었음을 의미합니다.
를 하세요.ref개체를 변경하려는 경우:
TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(ref t);
void DoSomething(ref TestRef x)
{
x = new TestRef();
x.Something = "Not just a changed TestRef, but a completely different TestRef object";
}
DoSomething, DoSomething을 에,t 원을참않음지를 하지 않습니다.new TestRef하지만 완전히 다른 물체를 가리킵니다.
이것은 불변 객체의 값을 변경하려는 경우에도 유용할 수 있습니다. 예를 들어, 예를 들어,string 할수없다니의 할 수 .string생성된 후에는 변경할 수 있습니다.하지만 사용함으로써ref값이 다른 다른 문자열에 대해 문자열을 변경하는 함수를 만들 수 있습니다.
사용하는 것은 좋은 생각이 아닙니다.ref필요 없는 한사용.ref메서드에 다른 항목에 대한 인수를 변경할 수 있는 자유를 제공합니다. 메서드의 호출자는 이러한 가능성을 처리하도록 코드화되어야 합니다.
또한 매개 변수 유형이 개체인 경우 개체 변수는 항상 개체에 대한 참조 역할을 합니다.이것은 다음과 같은 경우를 의미합니다.ref키워드가 사용됩니다. 참조에 대한 참조가 있습니다.이렇게 하면 위의 예에서 설명한 대로 작업을 수행할 수 있습니다.일 : 매변유예원형값시경인우이수개그나러예경▁((우:▁the▁is▁but)int이된 후 의 값이 됩니다.에서 이 매개 변수를 메서드 내에 할당하면 메서드가 반환된 후 전달된 인수 값이 변경됩니다.
int v = 1;
Change(ref v);
Debug.Assert(v == 5);
WillNotChange(v);
Debug.Assert(v == 5); // Note: v doesn't become 10
void Change(ref int x)
{
x = 5;
}
void WillNotChange(int x)
{
x = 10;
}
"값으로 기준 전달"과 "기준으로 매개 변수/인수 전달"을 구분해야 합니다.
저는 뉴스 그룹에 이 문제가 나올 때마다 신중하게 쓸 필요를 피하기 위해 그 주제에 대해 상당히 긴 기사를 썼습니다.
.NET에서 매개 변수를 메서드에 전달하면 복사본이 생성됩니다.값 형식은 값을 수정한 내용이 메서드 범위에 있으며 메서드를 종료하면 값이 손실됨을 의미합니다.
참조 유형을 전달할 때도 복사본이 만들어지지만 참조의 복사본입니다. 즉, 이제 동일한 개체에 대한 메모리에 두 개의 참조가 있습니다.따라서 참조를 사용하여 개체를 수정하면 개체가 수정됩니다.그러나 참조 자체를 수정하면(복사본임을 기억해야 함) 메서드를 종료할 때 변경사항도 손실됩니다.
이전에 사람들이 말했듯이, 할당은 참조의 수정이므로 손실됩니다.
public void Method1(object obj) {
obj = new Object();
}
public void Method2(object obj) {
obj = _privateObject;
}
위의 메서드는 원래 개체를 수정하지 않습니다.
당신의 예를 약간 수정한 것.
using System;
class Program
{
static void Main(string[] args)
{
TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(t);
Console.WriteLine(t.Something);
}
static public void DoSomething(TestRef t)
{
t = new TestRef();
t.Something = "Bar";
}
}
public class TestRef
{
private string s;
public string Something
{
get {return s;}
set { s = value; }
}
}
TestRef는 클래스(참조 개체)이므로 t 내부의 내용을 Ref로 전달하지 않고 변경할 수 있습니다.그러나 참조로 통과할 경우 TestRef는 원래 t가 가리키는 것을 변경할 수 있습니다. 즉, t가 다른 개체를 가리키도록 만들 수 있습니다.
와 함께ref다음과 같이 쓸 수 있습니다.
static public void DoSomething(ref TestRef t)
{
t = new TestRef();
}
그리고 메소드가 완료된 후에 변경됩니다.
변예)를 합니다.foo참조 유형(예:List<T>)는 "Object #24601" 양식의 객체 식별자를 보유합니다.문장을 가정해 보겠습니다.foo = new List<int> {1,5,7,9}; 인들원foo"Object #24601"(4개 항목으로 구성된 목록)을 보유합니다.그 때 부르는 것foo.Length묻습니다. #24601이합니다. 따라서 #24601은 4에 해당합니다.foo.Length4µs 같습니다.
한다면foo는 사용하지 됩니다.ref개체 #24601을 변경할 수 있습니다.변화의 로, 그한변화결과로의러,로,foo.Length더 이상 4와 같지 않을 수 있습니다.자체는 변경할 수 .foo #을입니다.Object #24601"을 계속 보관합니다.
싱패fooref매개 변수는 호출된 메소드가 객체 #24601 뿐만 아니라 다음과 같은 변경을 할 수 있도록 합니다.foo이 Object #하고 이에 를 저장할 수도 있습니다. #8675309에 할 수 .foo만약 그렇게 한다면,foo는 더 이상 "개체 #24601"을 보유하지 않고 "개체 #8675309"를 보유합니다.
실제로 참조 유형 변수는 "Object #8675309" 형식의 문자열을 포함하지 않으며 숫자로 의미 있게 변환할 수 있는 항목도 포함하지 않습니다.각 참조 유형 변수가 일부 비트 패턴을 보유하더라도 이러한 변수에 저장된 비트 패턴과 해당 변수가 식별하는 개체 간에는 고정된 관계가 없습니다.코드가 원래 개체를 식별한 참조를 보유하거나 알지 못하는 한 코드가 개체로부터 정보를 추출하고 나중에 다른 참조가 동일한 개체를 식별했는지 여부를 결정할 수 있는 방법은 없습니다.
이것은 C의 포인터에 포인터를 전달하는 것과 같습니다..NET에서는 원래 T가 가리키는 것을 변경할 수 있습니다. 개인적으로 .NET에서 그렇게 하고 있다면 디자인 문제가 있을 것입니다!
를 사용하여ref참조 유형이 포함된 키워드를 사용하면 참조에 대한 참조를 효과적으로 전달할 수 있습니다.여러 면에서 이는 다음과 같습니다.out하지만 이 .ref' parametered는 'ed parameter'입니다
ref다음 두 가지 범위에 대해 전역 영역으로 모방(또는 동작)합니다.
- 호출자
- 콜리.
그러나 값을 전달하는 경우에는 상황이 다릅니다.참조를 통해 값을 전달할 수 있습니다.이렇게 하면 예를 들어 메소드에 정수를 전달하고 메소드가 대신 정수를 수정하도록 할 수 있습니다.
나는 어디선가 관련된 행동에 대한 아름다운 묘사를 읽었다고 생각합니다.이런 식으로 진행됩니다.
C#에는 포인터(안전하지 않은 코드 제외)가 없기 때문에 "기준 전달"이 없습니다. 실제로 모든 것은 "값별 복사"입니다.복잡한 유형의 인스턴스만 실제로 참조를 값으로 유지하는 변수로 보아야 합니다.따라서 이들 "값"(실제 데이터를 가리키는 참조)은 메서드 호출에 복사됩니다.따라서 메소드 내에서 매개 변수는 동일한 개체를 참조하지만 참조를 보유하고 있는 변수는 원래 입력의 복사본입니다.
ref키워드를 지정하면 참조 호출로 변경됩니다.
언급URL : https://stackoverflow.com/questions/186891/why-use-the-ref-keyword-when-passing-an-object
'programing' 카테고리의 다른 글
| MongoDB에서 속성을 텍스트에서 날짜 유형으로 변환하려면 어떻게 해야 합니까? (0) | 2023.05.18 |
|---|---|
| Node.js/Mongoose에서 "VersionError: 일치하는 문서를 찾을 수 없습니다" 오류가 발생했습니다. (0) | 2023.05.18 |
| 목록 인덱스가 범위를 벗어남'을 예외로 처리하려고 합니다. (0) | 2023.05.18 |
| VB.NET에 새 스레드 생성 (0) | 2023.05.18 |
| "파서 오류 메시지:Global.asax의 "유형"을 로드할 수 없습니다. (0) | 2023.05.18 |