ref
구조체 형식(C# 참조)
구조체 형식 선언에 ref
한정자를 사용할 수 있습니다. ref struct
형식의 인스턴스는 스택에 할당되며 관리되는 힙으로 이스케이프할 수 없습니다. 이를 위해 컴파일러는 다음과 같이 ref struct
형식의 사용을 제한합니다.
ref struct
는 배열의 요소 형식일 수 없습니다.ref struct
는 클래스의 필드 또는 비ref struct
의 선언된 형식일 수 없습니다.ref struct
는 System.ValueType 또는 System.Object에 boxing할 수 없습니다.- 람다 식 또는 로컬 함수에서
ref struct
변수를 캡처할 수 없습니다. - C# 13
ref struct
이전에는 메서드에서 변수를async
사용할 수 없습니다. C# 13부터ref struct
변수는async
메서드의await
식과 동일한 블록에서 사용할 수 없습니다. 그러나 동기 메서드에서는ref struct
변수(예: Task 또는 Task<TResult>를 반환하는 메서드)를 사용할 수 있습니다. - C# 13 이전에는 반복기에서
ref struct
변수를 사용할 수 없습니다. C# 13부터yield return
문이 있는 코드 세그먼트에 없는 경우ref struct
형식 및ref
로컬을 반복기에서 사용할 수 있습니다. - C# 13 이전에는
ref struct
이(가) 인터페이스를 구현할 수 없습니다. C# 13부터ref
구조체는 인터페이스를 구현할 수 있지만 ref 안전 규칙을 준수해야 합니다. 예를 들어 boxing 변환이 필요하기 때문에ref struct
형식을 인터페이스 형식으로 변환할 수 없습니다. - C# 13 이전에는
ref struct
이(가) 형식 인수가 될 수 없습니다. C# 13부터ref struct
형식 매개 변수가where
절에allows ref struct
을(를) 지정할 때 형식 인수가 될 수 있습니다.
일반적으로 ref struct
형식의 데이터 멤버도 포함하는 형식이 필요한 경우 ref struct
형식을 정의합니다.
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
ref struct
를 readonly
로 선언하려면 형식 선언에서 readonly
및 ref
한정자를 결합합니다(readonly
한정자는 ref
한정자 앞에 와야 함).
public readonly ref struct ConversionRequest
{
public ConversionRequest(double rate, ReadOnlySpan<double> values)
{
Rate = rate;
Values = values;
}
public double Rate { get; }
public ReadOnlySpan<double> Values { get; }
}
.NET에서 ref struct
의 예는 System.Span<T> 및 System.ReadOnlySpan<T>입니다.
ref
필드
C# 11부터 다음 예제와 같이 ref
필드를 ref struct
에 선언할 수 있습니다.
public ref struct RefFieldExample
{
private ref int number;
public int GetNumber()
{
if (System.Runtime.CompilerServices.Unsafe.IsNullRef(ref number))
{
throw new InvalidOperationException("The number ref field is not initialized.");
}
return number;
}
}
ref
필드에는 null
값이 있을 수 있습니다. Unsafe.IsNullRef<T>(T) 메서드를 사용하여 ref
필드가 null
인지 확인합니다.
다음과 같은 방법으로 readonly
한정자를 ref
필드에 적용할 수 있습니다.
readonly ref
: 생성자 또는init
접근자 내에서만= ref
연산자를 사용하여 이러한 필드를 ref 다시 할당할 수 있습니다. 필드 액세스 한정자가 허용하는 모든 지점에서=
연산자를 사용하여 값을 할당할 수 있습니다.ref readonly
: 어떤 경우에도=
연산자를 사용하여 이러한 필드에 값을 할당할 수 없습니다. 그러나= ref
연산자를 사용하여 필드를 ref 다시 할당할 수 있습니다.readonly ref readonly
: 생성자 또는init
접근자에서만 이러한 필드를 ref 다시 할당할 수 있습니다. 어떤 경우에도 필드에 값을 할당할 수 없습니다.
컴파일러는 ref
필드에 저장된 참조가 참조보다 오래 되지 않도록 합니다.
ref
필드 기능을 사용하면 System.Span<T>와(과) 같은 형식을 안전하게 구현할 수 있습니다.
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;
// Omitted for brevity...
}
Span<T>
형식은 메모리의 연속 요소에 액세스하는 참조를 저장합니다. 참조를 사용하면 Span<T>
인스턴스가 참조하는 스토리지를 복사하지 않도록 할 수 있습니다.
삭제 가능한 패턴
삭제 가능한 ref struct
를 정의할 수 있습니다. 이렇게 하려면 ref struct
는 삭제 가능 패턴에 맞는지 확인해야 합니다. 즉 이 구조체에는 액세스 가능하고 매개 변수가 없으며 void
반환 형식을 갖는 인스턴스 Dispose
메서드가 있습니다. using 문 또는 선언을 일회용 ref struct
의 인스턴스와 함께 사용할 수 있습니다.
C# 13부터는 ref struct
형식에서 IDisposable을(를) 구현할 수도 있습니다. 그러나 오버로드 확인은 인터페이스 메서드보다 삭제 가능한 패턴을 선호합니다. 컴파일러는 적절한 Dispose
메서드를 찾을 수 없는 경우에만 IDisposable.Dispose
메서드로 해결합니다.
인터페이스를 구현하는 ref struct
형식에 대한 제한 사항
이러한 제한은 인터페이스를 구현하는 ref struct
형식이 필요한 ref 안전 규칙을 준수하도록 합니다.
ref struct
은(는) 자신이 구현하는 인터페이스의 인스턴스로 변환될 수 없습니다. 이 제한에는 매개 변수가 인터페이스 형식인 경우ref struct
형식을 인수로 사용할 때의 암묵적 변환이 포함됩니다. 이 변환은 ref 안전을 위반하는 boxing 변환으로 이어집니다.- 인터페이스 를 구현하는
ref struct
는 모든 인터페이스 멤버를 구현해야 합니다.ref struct
는 인터페이스에 기본 구현이 포함된 멤버를 구현해야 합니다.
컴파일러는 이러한 제한을 적용합니다. 인터페이스를 구현하는 ref struct
형식을 작성하는 경우 새 업데이트마다 새 기본 인터페이스 멤버가 포함될 수 있습니다. 이러한 새 메서드에 대한 구현을 제공할 때까지 애플리케이션은 컴파일되지 않습니다.
Important
인터페이스를 구현하는 ref struct
은(는) 나중에 소스 호환성이 손상되고 이진 호환성이 손상되는 변경이 발생할 가능성이 있습니다. ref struct
이(가) 다른 어셈블리에 정의된 인터페이스를 구현하고 해당 어셈블리가 해당 인터페이스에 기본 멤버를 추가하는 업데이트를 제공하는 경우 중단이 발생합니다.
소스 중단은 ref struct
이(가) 다시 컴파일할 때 발생합니다. 기본 구현이 있더라도 새 멤버를 구현해야 합니다.
이진 중단은 ref struct
형식 및 다시 컴파일하지 않고 외부 어셈블리를 업그레이드하고 업데이트된 코드가 새 메서드의 기본 구현을 호출하는 경우 발생합니다. 런타임은 기본 멤버가 액세스할 때 예외를 throw합니다.
C# 언어 사양
자세한 내용은 C# 언어 사양의 다음 섹션을 참조하세요.
ref
필드에 대한 자세한 내용은 하위 수준 구조체 개선 제안 노트를 참조하세요.
참고 항목
.NET