0

consider this cod here:

public ref struct RefValue <T> where T : unmanaged 
{
   public ref readonly T Item1;
   public RefTuple(ref T item1)
   {
      Item1 =  ref item1;
   }
}

    //This function gets a 'ref' directly to the dictionary value
    //and 'RefValue<T>' is a ref-struct which has a 'ref readonly field T'
    //to store args passed as 'ref param'
    public RefValue<Stats> GetStatsByType(TileType t)
    {
        return new RefValue<Stats>(ref CollectionsMarshal.GetValueRefOrAddDefault(_typeStats, t, out _));
    }
   
    //THIS LINE HERE:!
    //says: CS 1612: The return value is not a variable and therefore cannot be changed
    public ref readonly Stats ExampleAsRef => ref GetStatsByType(TileType.Blue).Item1;

I don't understand why... I am keeping everything in sync/aligned, like: the property returns ref readonly, the function returns ref readonly, the 'T' value of 'RefValue' is ref readonly, how does it come that he does want to accept that, I don't legit understand :/

Would be super cool if some1 has an answer to this, I do not..

Best regards

Stats is a simple struct, with some primitive fields. PS: am using .NET 7 RC2, mac OS X 10.15, C#11

PS2: here the missing types:

public struct Stats
{
/// <summary>
/// Count-Clicks, with maxTime inbetween   them
/// </summary>
    public int? Click;
    public int? Swaps;
    public int? Match;
    public int? RePainted;
    public int? Destroyed;

    public Stats()
    {
       Destroyed = 0;
       Click = 0;
       Swaps = 0;
       Match = 0;
       RePainted = 0;
    }
}

public enum TileType : short
{
    Red, Blue, Green, Purple, Violet,
    Length = Violet + 1, Empty = -1,
}

I also tried this, without any success as well:

   public ref readonly Stats GetStatsByType(TileType t)
    {
        return ref (new RefTuple<Stats>(ref CollectionsMarshal.GetValueRefOrAddDefault(TypeStats, t, out var existedB4))).Item1;
    }
Shpendicus
  • 83
  • 6
  • https://stackoverflow.com/questions/1747654/error-cannot-modify-the-return-value-c-sharp – scottdavidwalker Oct 19 '22 at 20:09
  • @scottdavidwalker how is this an answer to my question? its a totally different context, my function gives me back a REF STRUCT which hold a READONLY REF to a struct FIELD, not a method, nor a property, so its the original value!! – Shpendicus Oct 19 '22 at 20:12
  • On top, the "Item! is a ref-readonly pointer to a value of a dictionary! which is the ORIGINAL value, so it must work actually. – Shpendicus Oct 19 '22 at 20:14
  • 3
    Maybe you could produce a working code example rather than getting exasperated over a comment . . . – scottdavidwalker Oct 19 '22 at 20:20
  • @scottdavidwalker: This uses C# 11 features like [ref fields](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/ref-struct#ref-fields). I suspect it's a working code sample in that context. – StriplingWarrior Oct 19 '22 at 20:50
  • 2
    @StriplingWarrior - It’s missing the struct for Stats, TileTypes as well as the _typeStats information. Yes, we could probably quickly enough fix that by playing around with the code a bit but then you never truly know if you’re matching the OP’s scenario – scottdavidwalker Oct 19 '22 at 20:56
  • @scottdavidwalker ok you shall get the code, gimme a min.. – Shpendicus Oct 19 '22 at 21:18
  • @StriplingWarrior yes its indeed C# 11 and ACTUALLY It should work I do not know where I did monkey like mistake... – Shpendicus Oct 19 '22 at 21:19
  • `RefValue` is a value type, so GetStatsByType returns a copy of the original. You are then trying to return a reference to a location in that temporary object, which is not allowed. – Raymond Chen Oct 19 '22 at 21:20
  • @RaymondChen its a ref-struct, like Span which is fine, it keeps track of a pointer which lives longer than it does, so it gets passed around aswell. – Shpendicus Oct 19 '22 at 21:24
  • 1
    What I don't understand in general is why there is this amount of ref-ization to begin with. Maybe you are better off using actual reference types, e.g. classes, rather than trying to reimplement them confusingly. – Ray Oct 19 '22 at 22:01
  • Because 1) structs are have better performance when inited in collections, which in my case is a static readonly dictionary. 2) the semantic is just that, a data container with fields to store and be used to calculate stuff and at most to compare. and sometimes I need really blank copies for some caculations and then throw the struct away so that was nr 3) of reasons why I want them like this, but it does not matter anyway, the stuff I am trying should be working, its smth useful in general , independent of my situation. – Shpendicus Oct 19 '22 at 22:10
  • Structs will not be better in performance when you want them to act like classes (which @Ray perfectly points out) - you're using a chainsaw to hammer a screw into the wall... – riffnl Oct 19 '22 at 22:45
  • i am using a struct, to keep data in them, which gets updated some times, and it is stored/updated in the dictionary. Perfectly fine what I am doing in this context. Despite that, the issue is still unrelated to my choice of data structure, but rather why I can't get a readonly ref field back to it! this is the main topic here, if you can't/won't contribute to this, then spare your fingertips. – Shpendicus Oct 19 '22 at 22:55
  • For me personally, this seems like a legit bug, cause why else u shall not be allowed to get a "ref-readonly" to a location which lives outside of the scope of the ref struct, as does Span? the compiler should see that "RefValue.Item1" is in fact a ref readonly field and should allow the return of it as ref readonly... I will make a bug request – Shpendicus Oct 20 '22 at 11:24

0 Answers0