4

According the docs:

You can't declare a ref struct as a member of a class or a normal struct.

But I managed to compile and run this:

public ref struct RefStruct
{
    public int value;
}
public class MyClass
{
    public RefStruct Item => default;
}    
...       

MyClass c = new MyClass();
Console.WriteLine(c.Item.value);

Now RefStruct is a ref struct and it is a member of a class. Is this statement wrong in some cases?

UPDATE Now the docs have been updated to a more precise description.

9
  • Try changing the value in c.Item and you'll see what you're actually doing with your declaration :) Commented Jun 21, 2019 at 6:34
  • Change the line to public RefStruct Item { get; set; } = default; Does that compile? What is the difference? What about public RefStruct Item2() { return new RefStruct(); }? Is your code more similar to the former or the latter? Commented Jun 21, 2019 at 6:35
  • 1
    The docs are incorrect - or at least imprecisely worded. The compiler error is more accurate - Field or auto-implemented property cannot be of type 'Program.RefStruct' unless it is an instance member of a ref struct.. The key principle here is that the compiler is enforcing that the object lives on the stack. It won't allow anything that results in the object living on the heap (whether that is a field or a field-backed property). I'll leave feedback on the page for you. Commented Jun 21, 2019 at 6:40
  • 2
    What part of the error is confusing? It is saying you can't have a field (whether an explicit field, or an implicit field behind an auto property) that is a ref struct. If you want to do that, the answer is you can't. ;P Then what can you do in the setter? Whatever you want (e.g. new up the ref struct, write to the console etc etc). As long as you don't have an explicit or implicit field that is a ref struct. Any case you can think of is covered 100% by that error message. It is very precisely and accurately worded (unlike the docs). Commented Jun 21, 2019 at 6:48
  • 2
    @SeM As I said - the docs are incorrect / imprecise. I pointed him to a better source of information, the error message itself. I have left them feedback to fix the docs. I have tried to explain the principle that the compiler is enforcing. I am not sure what else I can say. Commented Jun 21, 2019 at 6:52

1 Answer 1

7

It is not field of your class but rather return value of a property getter - which is fine as it is just function return value.

Note that "as a member of a class" usually includes properties and probably should be changed to "field of a class".

If you would try to declare it as a class field (either directly or indirectly via auto-implemented property) this will require part of the class (the data for ref struct) to be allocated on the stack and the rest allocated in manged heap.

The code in the question defines non-autoimplemented property. As result there is no need for compiler to automatically create hidden field of the property type in the class. So while property result type is ref struct it actually is not stored in the class and hence does not violate requirement for this ref struct type not be included into any class. Note that even making setter method would be fine by itself - storing value for that property would be tricky, but you can safely store content of the ref struct (public int value; as in the post) in set and recreate it in get.

Sign up to request clarification or add additional context in comments.

4 Comments

You can't create a property of ref struct, the compiler will give an error: "Field or auto-implemented property cannot be of type 'RefStruct' unless it is an instance member of a ref struct."
Yea, I get it, I think the doc needs some improvements. @SᴇM I think you need to set the getter instead of using the auto one.
@joe Sure if you create just a Property with getter returning default, it will be the same as you have declared. For example: public RefStruct MyProperty { get { return default; } } and it's equivalent to RefStruct MyMethod() => default;.
@SᴇM I think I've added explanation about your comment - see if that's enough.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.