2

Apparently you cannot use the keyword "this" in a method in a struct. Note that in the below example I do not explicitly type "this" but it is implied when I reference the properties "X" or "Y".

My struct:

public struct Coord
{
    public int X;
    public int Y;
    public Coord(int x, int y)
    {
        X = x;
        Y = y;
    }
    // some other methods omitted

    public List<int> GetPossibles()
    {
        return LaurenceAI.Values.Where(n => LaurenceAI.Possibilities[X, Y, n]).ToList();
    }
}

usage example:

foreach(int numeral in targetCoord.GetPossibles())
{
   //do stuff
}

Error:

Error 1 Anonymous methods, lambda expressions, and query expressions inside structs cannot access instance members of 'this'. Consider copying 'this' to a local variable outside the anonymous method, lambda expression or query expression and using the local instead. C:\Projects\Sodoku\SodokuSolver\Sodoku\LaurenceAI.cs 367 74 Sodoku

Questions:

  1. What is the technical reason that a method in a struct cannot use keyword "this"?
  2. Is there an elegant way to fix this so that I don't have to type out the reflection code longhand every time I want a list of possible numerals for a given Coord?
  • 3
    https://stackoverflow.com/questions/15619407/why-do-i-have-to-copy-this-when-using-linq-in-a-struct-and-is-it-ok-if-i-do – test Dec 15 '15 at 23:52

1 Answers1

4

The reason is that structs are passed by value, not by reference. Using this in this context results in typically not what you want - it'll access the this pointer of the copy, not the outer object, and it'll be really confusing when any assignments you make aren't showing in the outer call. It's annoying in this specific circumstance, but in general it's stopping more weird errors.

The error message actually gives you a fairly reasonable solution - copy the values first. Do something like:

public List<int> GetPossibles()
{
    var localX = X;
    var localY = Y;
    return LaurenceAI.Values.Where(n => LaurenceAI.Possibilities[localX, localY, n]).ToList();
}
Chris Tavares
  • 29,165
  • 4
  • 46
  • 63
  • Yeah, wanting to capture `X` and `Y` directly was just like wanting to capture a `ref` parameter within a lambda (equally illegal). I guess you can also copy the entire struct value to a local struct variable, as in `{ var local = this; return LaurenceAI.Values.Where(n => LaurenceAI.Possibilities[local.X, local.Y, n]).ToList();`. That is closer to the suggestion in the error text. – Jeppe Stig Nielsen Dec 16 '15 at 00:16