2012-04-19 3 views
1

구조체 및 함수를 작성하여 참조로 구조체를 전달하려고합니다. 즉 구조체 값을 함수 내부에서 수정할 수 있습니다..NET에서 함수 매개 변수로 포인터를 사용하거나 "ref"키워드를 사용하는 것 사이에는 어떤 차이가 있습니까?

enum RoomType { Economy, Buisness, Executive, Deluxe }; 

struct HotelRoom 
{ 
    public int Number; 
    public bool Taken; 
    public RoomType Category; 

    public void Print() 
    { 
     String status = Taken ? "Occupied" : "available"; 
     Console.WriteLine("Room {0} is of {1} class and is currently {2}", 
      Number, Category, status); 
    } 
} 

이제이 구조체를 참조로 전달하기 위해 두 가지 방법을 발견했습니다.

//Using Pointer 
private unsafe static void Reserve(HotelRoom* room) 
{ 
    if (room->Taken) 
     Console.WriteLine("Cannot reserve room {0}", room->Number); 
    else 
     room->Taken = true; 
}  

//Using ref keyword. 
private static void Reserve(ref HotelRoom room) 
{ 
    if (room.Taken) 
     Console.WriteLine("Cannot reserve room {0}", room.Number); 
    else 
     room.Taken = true; 
}  

어떤 차이가 있습니까? 일반적으로 언제 포인터를 사용해야합니까? 그리고 언제 ref 키워드를 사용해야합니까? 엄지 손가락의

+2

변경 가능한 구조는 악합니다.클래스와 일반 매개 변수를 사용해야합니다. – SLaks

+0

포인터가있는'unsafe' 키워드의 필요성은 당신의 질문에 대해 무엇을 말합니까? – Oded

+0

C++ 용어로 생각하는 것 같습니다. 하지마. C#은 C++이 아닙니다. – SLaks

답변

1

포인터가 안전하지 않은 것으로 간주됩니다.

함수에 대한 포인터로 참조를 전달하는 것과 같이 안전하지 않은 컨텍스트에서 코딩하는 경우 다른 사람이 포인터를 다른 위치의 포인터로 변경할 수 있으며 가비지 데이터를 가져올 수 있습니다. 당신이 심판 키워드를 사용하는 경우

은, 문맥은 "안전한"이며, , 촬영카테고리 같은 만의 데이터를 가리키는 위치를 변경할 수 없습니다.

+0

당신이 가져온 가장 중요한 포인트는 "누군가 포인터를 다른 곳으로 옮겨서 쓰레기 데이터를 얻을 수있다"이다. 그거 하나? – Pritesh

+0

+1 할 지 묻는군요? 나는 편견이있어. :) – Nihil

+0

나는 "?" 실수로. 그것은 "+1", 당신은 arnswer 아주 좋았어. – Pritesh

3

간단한 규칙은 : 포인터를 사용하지 마십시오

.

포인터는 모호한 interop 또는 무딘 최적화를위한 것입니다.
일반적으로 안전하지 않은 코드는 사용하지 않아야합니다.

+0

동의 함. .NET에서는 포인터를 사용할 필요가 없습니다. 그것은'ref'와'out'을위한 것입니다. 그러나 프로젝트에 비 관리 코드를 포함하는 경우 포인터를 사용해야 할 수 있습니다. 이것이이 옵션이 존재하는 이유입니다. –

+0

@ Nico Schertler 2 장소 2 사용. 1) Interop 2) 최적화. – Pritesh

+0

@Pritesh : 그러나 포인터가 실제로 상황을 빠르게 만드는 시나리오는 거의 없습니다. 일반적으로, 당신이 물어야하는 경우에, 당신은 아마 안된다. (그리고 언제나 _measure_!) – SLaks

1

포인터는 C# 언어의 유용한 부분입니다. 포인터를 사용하는 것은 어렵지 않지만 진단하기가 어려울 수 있으므로주의 깊게 사용해야합니다. 포인터를 사용하면 특히 프로그램에서 많은 포인터를 사용할 때 가비지 수집기 기능을 방해합니다. 따라서 우리는 어쩌면을 고려한다 포인터를 사용하기 전에 다른 ways.For 세부 사항을 참조 찾아보십시오 :
http://www.c-sharpcorner.com/UploadFile/gregory_popek/WritingUnsafeCode11102005040251AM/WritingUnsafeCode.aspx
뭔가가 ref에 의해 전달되는 .NET에서는
Working with pointers in C#

+0

마치 해머가 언젠가 그것을 사용해야하지만 신중하게, 우리 자신의 발에 부딪쳐서는 안된다. – Pritesh

0

을, 호출 된 함수 포인터를 수신하는 그것을 매우 제한된 특정 상황을 제외하고는 복사가 금지됩니다. 포인터가 unsafe 코드에 제공되지 않으면 호출 된 함수의 실행 중에 만들어진 포인터의 사본이 호출 된 함수가 반환되기 전에 소멸되도록 보장됩니다. 문제의 포인터가 힙 개체의 일부를 가리키면 호출 사이트와 연결된 메타 데이터는 가비지 수집기가 해당 개체에 대한 참조를 찾을 위치를 알려줌으로써 방해를주지 않도록합니다.

unsafe 함수 또는 비 관리 코드에 의해 생성되거나 전달 된 포인터가 다릅니다. 안전하지 않은 함수 또는 관리되지 않는 코드에 포인터가 있으면 함수 호출보다 오래 걸리고 가비지 수집기에서 알 수없는 형식으로 저장할 수 있습니다. 가비지 콜렉터가 힙 오브젝트를 방해하지 않도록 명시 적으로 알 수있는 방법이 있지만 이러한 기술의 사용에는 위험이 따른다.

포인터를 사용하는 데 압도적 인 이유가없는 한 참조로 매개 변수를 전달할 때는 ref을 사용하십시오. 두 기술이 일관되게 올바르게 작동하는 경우 포인터를 전달하는 것만 큼 빠르다.