.NET은 참조 반환을 지원하지만 C #은 지원하지 않는다는 것을 읽었습니다. 특별한 이유가 있습니까? 왜 내가 다음과 같은 일을 할 수 없습니까?
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
답변
이 질문은 2011 년 6 월 23 일 에 제 블로그 의 주제였습니다 . 좋은 질문 감사합니다!
C # 팀은 C # 7에서이를 고려하고 있습니다. 자세한 내용은 https://github.com/dotnet/roslyn/issues/5233 을 참조하십시오.
업데이트 :이 기능은 C # 7에 도입되었습니다!
당신이 올바른지; .NET은 변수에 대한 관리되는 참조를 반환 하는 메서드를 지원 합니다. .NET은 다른 변수에 대한 관리 참조가 포함 된 로컬 변수 도 지원 합니다. 그러나 .NET은 가비지 수집 스토리를 지나치게 복잡하게하므로 다른 변수에 대한 관리되는 참조가 포함 된 필드 나 배열 을 지원하지 않습니다 . 또한 “변수에 대한 관리되는 참조”형식은 object로 변환 할 수 없으므로로 사용할 수 없습니다. 제네릭 형식 또는 메서드에 대한 형식 인수)
어떤 이유로 논평자 “RPM1984″는이 사실에 대한 인용을 요구했다. RPM1984 .NET의이 기능에 대한 정보는 CLI 스펙 파티션 I 섹션 8.2.1.1, “관리 포인터 및 관련 유형”을 읽으십시오.
이 두 기능을 모두 지원하는 C # 버전을 만드는 것은 전적으로 가능합니다. 그런 다음과 같은 일을 할 수 있습니다
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
그리고 그것을 호출
int a = 123;
int b = 456;
ref int c = ref Max(ref a, ref b);
c += 100;
Console.WriteLine(b); // 556!
나는 이러한 기능을 지원하는 C 번호의 버전을 구축하는 것이 가능하다는 것을 경험적으로 알고 내가 그렇게 때문에를 . 고급 프로그래머, 특히 관리되지 않는 C ++ 코드를 이식하는 사람들은 실제로 포인터를 사용하고 메모리를 고정시키는 데 큰 어려움을 겪지 않고 참조로 작업을 수행하는 더 많은 C ++과 같은 기능을 요구합니다. 관리되는 참조를 사용하면 가비지 수집 성능을 저하시키는 비용을 지불하지 않고도 이러한 이점을 얻을 수 있습니다.
우리는이 기능을 고려하여 실제로 다른 내부 팀에 피드백을받을 수있을 정도로 충분히 구현했습니다. 그러나 현재 우리의 연구에 따르면이 기능은 실제로 지원되는 언어 기능으로 만들기에 충분한 호소력이나 사용 사례가 충분하지 않다고 생각합니다 . 우선 순위가 높고 시간과 노력이 제한되어 있으므로이 기능을 곧 사용할 수 없습니다.
또한 제대로 수행하려면 CLR을 약간 변경해야합니다. 현재 CLR은 이러한 상황을 감지하는 검출기가 없기 때문에 환급 방법을 합법적 이지만 검증 할 수없는 것으로 취급합니다.
ref int M1(ref int x)
{
return ref x;
}
ref int M2()
{
int y = 123;
return ref M1(ref y); // Trouble!
}
int M3()
{
ref int z = ref M2();
return z;
}
M3은 M2 로컬 변수의 내용을 반환하지만 해당 변수의 수명이 끝났습니다! 스택 안전 을 명확하게 위반 하지 않는 참조 반환의 사용을 결정하는 검출기를 작성할 수 있습니다 . 우리가 할 일은 그러한 검출기를 작성하는 것이며, 검출기가 스택 안전을 증명할 수 없다면 프로그램의 해당 부분에서 ref return을 사용할 수 없습니다. 그렇게하는 것은 엄청난 양의 개발 작업이 아니지만 테스트 팀이 실제로 모든 상황을 해결하도록하는 것은 많은 부담입니다. 기능의 비용이 현재의 이점보다 비용을 능가하지 않는 수준으로 증가시키는 것은 또 다른 일입니다.
이 기능이 왜 필요한지 설명해 주시면 감사하겠습니다 . 실제 고객이 원하는 이유에 대한 정보가 많을수록 언젠가는 제품에 정보를 제공 할 가능성이 높아집니다. 귀여운 작은 기능이며 충분한 관심이 있다면 어떻게 든 고객에게 제공 할 수 있기를 바랍니다.
(또한 관련 질문을 참조 는 C #에서 변수에 대한 참조를 반환 할 수 있습니까? 그리고 ++ 나 C와 같은 C #을 함수 내에서 참조를 사용할 수 있습니까? )
답변
값 유형에 대한 참조를 리턴하는 메소드에 대해 이야기하고 있습니다. 내가 아는 C #의 내장 예제는 값 유형의 배열 접근 자입니다.
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
이제 해당 구조체의 배열을 만듭니다.
var points = new Point[10];
points[0].X = 1;
points[0].Y = 2;
이 경우 points[0]
배열 인덱서 는 struct에 대한 참조를 반환합니다. 이와 같은 “참조 반환”동작을 갖는 고유 인덱서 를 작성하는 것은 불가능합니다 (예 : 사용자 지정 컬렉션의 경우).
나는 C # 언어를 디자인하지 않았기 때문에 그것을 지원하지 않는 모든 추론을 알지 못했지만 짧은 대답은 다음과 같습니다. 우리는 그것을하지 않고 잘 지낼 수 있습니다.