[C#] ‘ref’와 ‘out’키워드의 차이점은 무엇입니까?

함수에 의해 수정 될 수 있도록 객체를 전달해야하는 함수를 만들고 있습니다. 차이점은 무엇입니까?

public void myFunction(ref MyClass someClass)

public void myFunction(out MyClass someClass)

어느 것을 사용해야하며 왜 그런가요?



답변

ref함수에 들어가기 전에 객체가 초기화 out되었음을 컴파일러에 알리고 함수 내부에서 객체가 초기화 될 것을 컴파일러에 지시합니다.

동안은 그래서 ref두 가지 방법 인, out아웃 전용입니다.


답변

ref수정 수단 :

  1. 값이 이미 설정되어 있으며
  2. 메소드는이를 읽고 수정할 수 있습니다.

out수정 수단 :

  1. 값이 설정되지 않고 설정 될 때까지 메소드가 읽을 수 없습니다 .
  2. 메소드 리턴하기 전에 설정 해야합니다 .

답변

Dom이 Peter의 칸막이에 TPS 보고서에 대한 메모에 대해 등장한다고 가정 해 봅시다.

Dom이 심판 주장이라면, 그는 메모 사본을 인쇄했을 것입니다.

Dom이 논쟁의 여지가 없다면, Peter는 그와 함께 가져갈 메모의 새 사본을 인쇄하게 할 것입니다.


답변

나는 설명을 위해 내 손을 시험해 볼 것이다.

가치 유형이 올바르게 작동하는 방식을 이해하고 있다고 생각합니까? 값 유형은 (int, long, struct 등)입니다. ref 명령없이 함수로 보내면 데이터가 복사 됩니다 . 함수에서 해당 데이터에 대한 모든 작업은 원본이 아닌 사본에만 영향을 미칩니다. ref 명령은 ACTUAL 데이터를 보내고 변경 사항은 함수 외부의 데이터에 영향을줍니다.

혼란스러운 부분, 참조 유형을 확인하십시오.

참조 유형을 만들 수 있습니다.

List<string> someobject = new List<string>()

someobject 를 새로 만들면 두 부분이 생성됩니다.

  1. someobject에 대한 데이터를 보유하는 메모리 블록입니다 .
  2. 해당 데이터 블록에 대한 참조 (포인터).

이제 당신이 ref없이 메소드 에 어떤 객체 를 보낼 때 데이터가 아닌 참조 포인터를 복사합니다 . 이제 당신은 이것을 가지고 있습니다 :

(outside method) reference1 => someobject
(inside method)  reference2 => someobject

동일한 객체를 가리키는 두 개의 참조 reference2를 사용하여 일부 객체 의 속성을 수정하면 reference1이 가리키는 동일한 데이터에 영향을 미칩니다.

 (inside method)  reference2.Add("SomeString");
 (outside method) reference1[0] == "SomeString"   //this is true

reference2를 널 아웃하거나 새 데이터를 가리키면 reference1 또는 data1이 가리키는 데이터에 영향을 미치지 않습니다.

(inside method) reference2 = new List<string>();
(outside method) reference1 != null; reference1[0] == "SomeString" //this is true

The references are now pointing like this:
reference2 => new List<string>()
reference1 => someobject

이제 객체 에 대한 참조로 메소드 를 보내면 어떻게됩니까 ? 실제 기준SomeObject의이 방법에 보내지. 따라서 이제 데이터에 대한 참조가 하나만 있습니다.

(outside method) reference1 => someobject;
(inside method)  reference1 => someobject;

그러나 이것은 무엇을 의미합니까? 그것은 두 가지 주요한 것을 제외하고 ref가 아닌 객체를 보내는 것과 정확히 동일하게 작동합니다.

1) 메소드 내부의 참조를 무효화하면 메소드 외부의 참조를 무효화합니다.

 (inside method)  reference1 = null;
 (outside method) reference1 == null;  //true

2) 이제 완전히 다른 데이터 위치를 가리키는 참조를 지정할 수 있으며 함수 외부의 참조는 이제 새 데이터 위치를 가리 킵니다.

 (inside method)  reference1 = new List<string>();
 (outside method) reference1.Count == 0; //this is true


답변

심판에 아웃 .

out요구 사항에 적합한 곳이면 어디에서나 사용 하십시오.


답변

밖:

C #에서 메서드는 하나의 값만 반환 할 수 있습니다. 둘 이상의 값을 반환하려면 out 키워드를 사용할 수 있습니다. 출력 수정자는 참조 기준으로 반환됩니다. 가장 간단한 대답은 키워드 “out”을 사용하여 메소드에서 값을 얻는 것입니다.

  1. 호출 함수에서 값을 초기화 할 필요는 없습니다.
  2. 호출 된 함수에 값을 할당해야합니다. 그렇지 않으면 컴파일러에서 오류를보고합니다.

심판 :

C #에서는 int, float, double 등과 같은 값 형식을 메서드 매개 변수의 인수로 전달하면 값으로 전달됩니다. 따라서 매개 변수 값을 수정하면 메소드 호출의 인수에 영향을 미치지 않습니다. 그러나“ref”키워드로 매개 변수를 표시하면 실제 변수에 반영됩니다.

  1. 함수를 호출하기 전에 변수를 초기화해야합니다.
  2. 메소드의 ref 매개 변수에 값을 지정하지 않아도됩니다. 값을 변경하지 않으면 “ref”로 표시해야합니까?

답변

개 확장, 고양이 예. ref가있는 두 번째 메소드는 호출자가 참조하는 오브젝트를 변경합니다. 따라서 “고양이”!!!

    public static void Foo()
    {
        MyClass myObject = new MyClass();
        myObject.Name = "Dog";
        Bar(myObject);
        Console.WriteLine(myObject.Name); // Writes "Dog". 
        Bar(ref myObject);
        Console.WriteLine(myObject.Name); // Writes "Cat". 
    }

    public static void Bar(MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }

    public static void Bar(ref MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }