-
This is revived from dotnet/roslyn#62243, which enables the following: ref struct R1<T>
{
}
ref struct R2<T>
{
public ref R1<T> F; // error CS9050: A ref field cannot refer to a ref struct.
} The Roslyn team member closed the issue as a language design issue |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
low-level-struct-improvements.md says:
So, one way you could help us make progress on this is to let us know how you plan on using it. Because C# does not have an explicit lifetimes syntax a la Rust and likely will never have one, there are major challenges to allowing ref fields of ref struct type. It changes the language from allowing only a bounded number of ref-indirections (e.g. For the existing bounded design we have made things work by introducing a number of distinct "well known" safe-contexts which equal the number of ref-indirections that can be expressed. Once RFRS is possible, there will probably be either a need for safe-contexts at a certain depth of nesting to be equal (which heavily constrains use sites), or, for some amount of unsafety to be present. |
Beta Was this translation helpful? Give feedback.
-
Here is my use case. public class MyObj;
public class MyObjFormatter : IMessagePackFormatter<MyObj?>
{
public MyObj? Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
options.Security.DepthStep(ref reader);//those two lines are always togather
//codes that do deserialization
MyObj obj = new();
reader.Depth--;//those two lines are always togather
return obj;
}
public void Serialize(ref MessagePackWriter writer, MyObj? value, MessagePackSerializerOptions options)
{
throw new NotImplementedException();
}
} So I want to simplify it with using scope pattern. public MyObj? Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
using (new DepthScope(ref reader, options))
{
//codes that do deserialization
MyObj obj = new();
return obj;
}
} Note that public readonly ref struct DepthScope
{
readonly ref MessagePackReader _reader;//not allowed
public DepthScope(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
_reader = ref reader;
options.Security.DepthStep(ref reader);
}
public void Dispose()
{
_reader.Depth--;
}
} But this is not allowed. public readonly unsafe ref struct DepthScope
{
readonly MessagePackReader* _reader;
public DepthScope(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
fixed (MessagePackReader* ptr = &reader)
{
_reader = ptr;
}
options.Security.DepthStep(ref reader);
}
public void Dispose()
{
_reader->Depth--;
}
} Basicly, It is the case where you want to write a using scope pattern that involves ref struct param. |
Beta Was this translation helpful? Give feedback.
There is no way to have a mutable
ref
to aref struct
without adding explicit lifetimes to the language. At the moment there are no plans for doing that. It would be a rather significant syntax update, even if we got it in through annotations in attributes, and it would need significant justification. That hasn't manifested.I think it's likely that we will get
ref readonly
toref struct
in .NET 11 or soon after. That is mostly an exercise in proving it's safe, updating a few rules and removing a few errors in the compiler. From there experts can useunsafe
to get mutable access to the value in the cases they are able to convince themselves the lifetimes are correct.