2009-09-22 2 views
4

ref 키워드를 사용하여 StringBuilder, string 및 MemoryStream과 같은 참조 형식을 전달하는 개발자와 함께 작업합니다. 그들은 참조 자체를 실제로 변경해야하는지 여부에 관계없이이 작업을 수행합니다.ref 키워드를 사용하여 참조 형식 전달하기 기본적으로

public void ExampleMethod(ref MemoryStream ms) 
{ 
    byte b=ms.ReadByte(); 
    ... 
    // No changing of actual ms reference such as: ms=new MemoryStream(); 
} 

거의 항상이 메서드는 개체를 사용하고 참조를 변경하지 않고 반환합니다. 불변의 타입, 즉 문자열의 경우, 이것은 때때로 필요 합니다만, 변경 가능한 타입의 경우는 왜입니까?

내게는 이것이 정말로 필요로하는 것보다 더 관대하다는 점에서 유지 보수가 용이하지 않은 코드로 이어질 수 있다는 점에서 약간의 "코드 냄새"가 있습니다.

그러나 개발자와 함께하기에 충분할 정도로 심각합니다. 내 intial 느낌은 예,하지만 어쩌면 너무 pedantic입니까?

+2

@Ash - 개발자에게 http://www.yoda.arachsys.com/csharp/parameters.html –

답변

17

아마 그 개발자에게 그가 왜 그렇게하는지 물어볼 수 있습니다. 아마 그가 (잘못) 생각하면 더 뛰어난 것 같습니까? 어쩌면 그 개발자는 C++ 개발자이며, ref를 사용하는 것이 C++에서 포인터를 사용하는 것과 비슷하다고 생각합니까?

그가 C++ 배경에서 온 사람이라면 왜 개발자가 그 일을하는지 물어볼 것이며 이것이 필요하지 않다는 것을 그에게 설명 할 것입니다. 그것은 성능을 향상시키지 못하며 대신 참조를 변경할 수 있으므로 메소드에 다른 의미를 부여한다는 것과 메소드가 참조를 변경할 필요가있을 때만 ref 키워드 만 사용해야한다는 것입니다.

저는 현학적이라고 생각하지 않습니다. 숙련 된 개발자조차도 그가 사용하고있는 새로운 언어의 모든 입/출력을 알지 못합니다. 당신이 그걸 설명하면, 그는 새로운 것을 배울 것이고, 아마도 그는 감사 할 것입니다. :)

+0

@ Frederik을 읽으라고 권장합니다. 예, 그들은 C++ 배경에서 왔습니다. 나는 당신이 공연에 대한 beleief에 대해 옳을 수도 있다고 생각합니다. – Ash

-1

ref 키워드는 값 유형 (ValueType에 속하는 것)을 수정할 때만 유용합니다. 값 유형은 이해가되지 않는 등 Stream 후손 또는 StringBuilder 같은 개체 참조 또는 클래스 ref를 사용 float 등 일 등 int, byte, char, struct, 그리고 확실히 코드 냄새입니다.

StringBuilder 참조를 ref으로 전달해야 할 필요가있는 유일한 경우는 문자열 값을 Win32와 마샬링 할 때입니다.

+0

나는 topicstarter가 이것을 알고 있다고 생각한다. :) 그의 질문은 조금 다릅니다. :) –

+1

@ 마이크, 참조 유형에 대한 참조를 사용하는 것이 완전히 합리적 인 확실한 합리적인 상황이 있습니다 (지나치게 일반적이지는 않습니다). 전형적인 예는 실제 참조를 교환하는 스왑 기능입니다. – Ash

+0

참조 유형에 대한 참조/출력 사용은 특정 상황에서 가장 명확하게 적용됩니다. 한 예는'Dictionary.TryGetValue (key, out value)'입니다. –

4

개발자가 "ref"키워드가 좋은 점을 오해 한 것일 수 있으므로 너무 성급한 것으로 생각하지 않습니다. 이 절대적으로 필요합니다.이 사용되어야합니다. 즉, 메서드가 보장되거나 "가장 재미있는"것이 아니라 다른 것으로 참조를 바꿀 가능성이 있음을 나타냅니다.

업데이트를 통신하는 방법에 관해서는
은 ... 흠, 그는 모든 일에 심판을 가하고 왜 뒤에 동기에 어쩌면 다소 달라집니다. 성능 향상을 원한다면 StopWatch.StartNew()을 사용하고 참조의 유무에 관계없이 메소드에 전달하십시오. 나는 그것을 시도하지 않았지만 성능 차이가 새로운 참조를 만드는 데있을 수 있다고 생각할 것이다. 그리고 그것은 작은 것이어야한다.

의도 한대로 기능을 사용하고 의도를 표현해야합니다.ref 또는 out 매개 변수를 가진 메소드를 볼 때 전달 된 인스턴스를 완전히 변경하거나 메소드가 전달 된 객체를 초기화하는 것으로 예상됩니다. 이러한 목적으로 이러한 키워드를 사용하지 않으면 불필요한 키워드로 메소드 호출을 혼란 시키거나 사용 된 API와 관련하여 잘못된 기대치를 설정함으로써 동료 프로그래머를 혼동시킬 수 있습니다.

+0

@ 프랭크, 지금은 (프로그래머를 위해) 논쟁의 여지가없는 경기에 빠지지 않고 잘 전달할 수있는 문제를 가지고 있습니다. 나는 내가 추측하는 몇 가지 사실과 증거가 필요할 것이다. – Ash

3

오해입니다. 메서드에 대한 참조를 전달하는 데 ref 키워드가 필요할 것입니다. 이 경우 개발자에게 문의해야합니다.

키워드가 필요하지 않을 때 ref 키워드를 사용하는 유일한 이유는 나중에이 메서드를 변경하여 개체를 대체 할 수있게하는 것입니다. 이것은 당신이 정말로 필요할 것으로 예상되는 곳에서만 사용해야합니다. 일반적으로 여러분은 상상할 수있는 모든 가능한 요구 사항이 아니라 현재의 요구 사항만을 코딩해야합니다.

어떤 이유로 든 필요하지 않은 ref을 발견하면 코드에서 제거해야합니다. 캡슐화의 원칙에 따라, 메소드는 필요한 것보다 매개 변수 값에 더 많은 권한을 부여하면 안됩니다.

일반적으로 ref 키워드는 거의 사용되지 않아야합니다. 대부분의 경우 객체 지향 접근 방식을 대신 사용할 수 있습니다. Double.TryParse 메소드와 같이 성능상의 이유로 값 유형과 함께 사용되지만 참조 유형이없는 경우가 있습니다.

6

확실히 가져올만한 가치가 있습니다. 필자는이 점을 여러 번 보아 왔으며 개발자가 형식 시스템을 이해하지 못해 항상 올바른 코드를 작성하고 유지 관리 할 수있는 코드를 작성해야하기 때문입니다.

분명히 필요하지는 않지만 어디에서 객체 자체의 내용을 변경하고 싶은지 찾을 수 있습니다. StringBuilder에 추가하는 것이 이상적입니다. 그런 다음 정교하게 ref 수정자를 사용하는 이유를 묻습니다. 그것이없이 잘 작동합니다 지적하십시오.

언제든지 parameters articlereference/value type article으로 문의하십시오.

+0

Jon, 개발자가 "Jon Skeet"에 대해 많이 들었으므로 기사가 매우 편리해야합니다.) 및 StackOverflow. – Ash

관련 문제