6

C# 프로그램에서는 목록에서 개체를 삭제하는 메서드를 만들었습니다. 사용자가 삭제할 항목의 색인을 입력하면 사용자는 삭제를 확인하도록 요청하고 사용자가 확인하면 항목이 목록에서 제거됩니다. 그렇지 않으면 목록이 동일하게 유지됩니다.
메서드에 인수를 전달하는 가장 좋은 방법은 확실하지 않습니다. 나는 오류가 할당되지 않은 지역 변수의 사용 '고객'아웃 된 매개 변수는 '고객을 얻을로C#에서는 값으로 매개 변수를 전달하고 동일한 변수를 반환해야합니까? 아니면 참조로 전달해야합니까?

static void DeleteCustomer(out List<Customer> customers) 
{ 
    // ...display list of objects for user to choose from... 
    int deleteId = ReadInt("Enter ID of customer to delete: "); 
    Console.Write("Are you sure you want to delete this customer?"); 
    if (Console.ReadLine().ToLower() == "y") 
    { 
     customers.RemoveAt(deleteId); 
    } 
} 

은 위의 코드가 작동하지 않습니다 나는 (AN out 매개 변수로) 참조 목록을 통과 노력 '는 현재 제어를 떠나기 전에 할당되어야합니다..

static List<Customer> DeleteCustomer(List<Customer> customers) 
{ 
    int deleteId = ReadInt("Enter ID of customer to delete: "); 
    Console.Write("Are you sure you want to delete this customer?"); 
    if (Console.ReadLine().ToLower() == "y") 
    { 
     customers.RemoveAt(deleteId); 
    } 
    return customers; 
} 

// ...which would be called from another method with: 
List<Customer> customers = DeleteCustomer(customers); 

을하지만 같은 변수가 값에 의해 전달하고 반환으로이 효율적으로하지 않는 것 :이처럼, 내가 값 목록을 전달하고 동일한 목록을 반환 할 수 생각했다.

이 경우 인수를 전달하는 가장 효율적인 방법은 무엇입니까?

+1

목록 은 자동으로 참조로 전달되므로 반환 할 필요가 없습니다. 호출 한 메소드는 전달 된 List를 참조하는 변경 사항을 확인합니다. – user469104

+2

참조 : [매개 변수 전달 C# - Jon Skeet 저] (http://www.yoda.arachsys.com/csharp/parameters.html). 또한 두 번째 방법을 시도해보십시오. 목록을 반환하지 않고 변경된 것을 볼 수 있습니다. 이는 참조 유형의 주소가 값에 의해 전달되기 때문입니다. ** 그러나 중요하게 **, 당신은 효율성 *에 대해 지금은 걱정하지 않아야합니다. 의도를 더 명확하게 전달하는 코드 작성을 고려하고 나중에 성능 향상을 찾습니다. – Habib

+0

두 번째 메소드의 반환 유형은'void '입니다. –

답변

4

List 등 모든 참조 유형은 참조으로 전달되며 복사본이 아닙니다. 이 매개 변수의 할당을 의미 하듯이, 그것은 참조 를 전달 말을 매우 다른 것을

참고가 IT가하는

을하지 않는 호출자에게 전파는 의미 그 수정 개체 (예 : RemoveAt에 의해 수행되는 개체)는 자동으로 호출자에게 전파됩니다.

따라서 그냥 전달하십시오. 반환 값 또는 out/ref 매개 변수가 필요하지 않습니다.

당신은 아주 드물게 참조 유형 out/ref를 사용하지되며, 값 유형에 사용하는 경우, 성능 차이는 프로파일 및 확인을 만들었습니다하지 않는 한 당신이 그것에 대해 걱정하지 않도록 반환에 비해 너무 작은 것 문제가 발생합니다. 가장 관용적 인 의미를 사용하십시오.

+2

'모든 참조 유형과 마찬가지로리스트는 객체에 대한 참조로 전달되며 사본이 아닙니다. 즉, 수정 사항이 자동으로 발신자에게 전파됩니다. ' 이것은 정확하지 않습니다. 전달 된 객체에 'null'또는 새 인스턴스를 할당 할 수 없습니다. 참조 유형의 주소는 값으로 전달됩니다. – Habib

+1

@Habib 완전히 동의했습니다. 참조로 전달됩니다. * by * reference가 아닙니다. 참조로 참조를 전달하는 것은 다릅니다. 너에게 더 이해가되는 말씨가 있니? 때로는 포인터가 있었으면 좋겠다. 설명하기가 훨씬 쉬워졌다. 또한 (전달하는 동안) 전파 문장을 명확하게하기 위해 편집했다. – BradleyDotNET

+3

그것의 까다로운 진술, 나는 ref/out 키워드가 사용되지 않는 한 C#의 어떤 것도 참조로 전달되지 않는다고 더 많이 말합니다. 참조 유형의 경우 참조/주소가 값으로 전달됩니다. – Habib

2

C#에서 매개 변수는 값으로 전달됩니다. 즉, 매개 변수를 메서드에 전달하면 매개 변수의 복사본이 전달됩니다. C#은 값 (int와 같은)과 참조 (모든 클래스와 같은)에 따라 유형을가집니다. C#은 스택 (모든 varaibles를 밀 때)과 힙을 포함합니다. 값 유형의 값은이 스택에서 직접 푸시되며 참조 유형의 참조는 스택에서 푸시되고 참조 된 값은 힙에 푸시됩니다.
참조 유형 (예 : 목록)을 전달하면 참조 복사본이 만들어 지지만이 복사본은 같은 개체를 가리키고 있습니다. 따라서 어떤 변경은 참조를 변경하지 않는 한 객체에 직접 영향을 미칩니다 (assigmet 사용). 그러나 이것은 사용자가 아닙니다. 코드에 의해

이 수 :

static void DeleteCustomer<T>(List<T> customers) 
    { 
     Console.WriteLine("Enter ID of customer to delete: "); 
     int deleteId; 
     if (int.TryParse(Console.ReadLine(), out deleteId)) // if the input is an int 
     { 
      Console.Write("Are you sure you want to delete this customer?"); 
      if (Console.ReadLine().ToLower() == "y") 
      { 
       customers.RemoveAt(deleteId); 
      } 
     } 
     else 
     { 
      Console.WriteLine("This is not valid Id"); 
     } 
    } 

당신이 심판에 대해 내가 너무 당신을 도울 수있는 아웃 키워드를 알고 싶어하지만,이 예를 들어 neccesary없는 경우

.

관련 문제