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변수는await메서드의async식과 동일한 블록에서 사용할 수 없습니다. 그러나 동기 메서드에서는ref struct변수(예: Task 또는 Task<TResult>를 반환하는 메서드)를 사용할 수 있습니다. - C# 13 이전에는
ref struct에서 변수를 사용할 수 없습니다. C# 13부터ref struct문이 있는 코드 세그먼트에 없는 경우ref형식 및yield return로컬을 반복기에서 사용할 수 있습니다. - C# 13 이전에는
ref struct이(가) 인터페이스를 구현할 수 없습니다. C# 13부터ref구조체는 인터페이스를 구현할 수 있지만 ref 안전 규칙을 준수해야 합니다. 예를 들어 boxing 변환이 필요하기 때문에ref struct형식을 인터페이스 형식으로 변환할 수 없습니다. - C# 13 이전에는
ref struct이(가) 형식 인수가 될 수 없습니다. C# 13부터ref struct형식 매개 변수가allows ref struct절에where을(를) 지정할 때 형식 인수가 될 수 있습니다.
일반적으로 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 필드
다음 예제와 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: 생성자 또는 내에서만= ref연산자를 사용하여 이러한 필드를init할 수 있습니다. 필드 액세스 한정자가 허용하는 모든 지점에서=연산자를 사용하여 값을 할당할 수 있습니다. -
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는 삭제 가능 패턴에 맞는지 확인해야 합니다. 즉, 액세스 가능하고 매개 변수가 없으며 반환 형식이 있는 인스턴스 Dispose 메서드가 있습니다 void .
using 문 또는 선언을 일회용 ref struct의 인스턴스와 함께 사용할 수 있습니다.
C# 13부터는 IDisposable 형식에서 ref struct을(를) 구현할 수도 있습니다. 그러나 오버로드 확인은 인터페이스 메서드보다 삭제 가능한 패턴을 선호합니다. 컴파일러는 적절한 IDisposable.Dispose 메서드를 Dispose 찾을 수 없는 경우에만 메서드로 확인됩니다.
인터페이스를 구현하는 ref struct 형식에 대한 제한 사항
이러한 제한은 인터페이스를 구현하는 ref struct 형식이 필요한 ref 안전 규칙을 준수하도록 합니다.
-
ref struct은(는) 자신이 구현하는 인터페이스의 인스턴스로 변환될 수 없습니다. 이 제한에는 매개 변수가 인터페이스 형식인 경우ref struct형식을 인수로 사용할 때의 암묵적 변환이 포함됩니다. 이 변환은 ref 안전을 위반하는 boxing 변환으로 이어집니다.ref struct메서드를 명시적 인터페이스 선언으로 선언할 수 있습니다. 그러나 이러한 메서드는 형식 매개 변수가allows ref struct유형을 지정하는 제네릭 메서드에서만 액세스할 수 있습니다. - 인터페이스 을 구현하는
ref struct은 모든 인스턴스 인터페이스 멤버를 구현해야 합니다. 인터페이스에 기본 구현이 포함되어 있는 경우에도ref struct인스턴스 멤버를 구현해야 합니다.
컴파일러는 이러한 제한을 적용합니다. 인터페이스를 구현하는 ref struct 형식을 작성하는 경우 새 업데이트마다 새 기본 인터페이스 멤버가 포함될 수 있습니다. 새 인스턴스 메서드에 대한 구현을 제공할 때까지 애플리케이션은 컴파일되지 않습니다. 기본 구현을 사용하여 static 인터페이스 메서드에 대한 특정 구현을 제공할 수 없습니다.
중요합니다
인터페이스를 구현하는 ref struct은(는) 나중에 소스 호환성이 손상되고 이진 호환성이 손상되는 변경이 발생할 가능성이 있습니다. 다른 어셈블리에 정의된 인터페이스를 구현하고 해당 어셈블리가 해당 인터페이스에 기본 멤버를 추가하는 업데이트를 제공하는 경우 ref struct 중단이 발생합니다.
소스 중단은 ref struct다시 컴파일할 때 발생합니다. 기본 구현이 있더라도 새 멤버를 구현해야 합니다.
이진 중단은 ref struct 형식 및 다시 컴파일하지 않고 외부 어셈블리를 업그레이드하고 업데이트된 코드가 새 메서드의 기본 구현을 호출하는 경우 발생합니다. 런타임은 기본 멤버가 액세스할 때 예외를 throw합니다.
C# 언어 사양
자세한 내용은 C# 언어 사양의 다음 섹션을 참조하세요.
ref 필드에 대한 자세한 내용은 하위 수준 구조체 개선 제안 노트를 참조하세요.
참고 항목
.NET