우선 이 구조체를 in 매개변수로 취하는 메서드를 작성할 수 있다. 복사본이 생성되지 않을 것이기 때문이다. 하지만 이렇게 메서드를 작성하면 호출 코드가 어색해진다. 다음 코드를 살펴보자.
double magnitude = VectorUtilities.Magnitude(vector);
이 코드는 그리 보기 좋지 않다. 확장 메서드를 사용하는 방법도 있는데, 다음과 같이 확장 메서드를 작성하면 메서드를 호출할 때마다 새로운 복사본이 생성된다.
public static double Magnitude(this Vector3D vector)
성능과 가독성 중 하나를 택해야 하는 상황은 유쾌하지 않다. C# 7.2부터는 이러한 문제에 대한 합리적이고 예상 가능한 해법을 제공하는데, 확장 메서드의 첫 번째 매개변수에 ref나 in 한정자를 사용할 수 있다. 이 한정자는 this 한정자 앞이나 뒤에 둘 수 있다. 확장 메서드의 역할이 그저 계산을 위한 것이라면 in 매개변수를 사용하는 것이 좋겠다. 하지만 기존 객체의 값을 변경해야 하는 상황이라면, 새로운 객체를 만들고 그 값을 복사해 주는 대신에 ref 한정자를 사용하는 것이 좋다. 다음 예제는 Vector3D에 대해 간단한 확장 메서드를 작성한 두 가지 예다.
예제 13-18 ref와 in을 사용하는 확장 메서드 ▶ Vector3DExtensions.cs
public static double Magnitude(this in Vector3D vec) =>
Math.Sqrt(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z);
public static void OffsetBy(this ref Vector3D orig, in Vector3D off) =>
orig = new Vector3D(orig.X + off.X, orig.Y + off.Y, orig.Z + off.Z);