C
C#14mo ago
EddieV

❔ Using `with` to create a new record in return statement result in an error

private Point GetNewPosition(Commands command, Point position)
{
if (command == Commands.MoveNorth) return position with { Y++ };
if (command == Commands.MoveSouth) return position with { Y-- };
if (command == Commands.MoveEast) return position with { X++ };
if (command == Commands.MoveWest) return position with { X-- };
return null;
}
public record Point(int X, int Y);
private Point GetNewPosition(Commands command, Point position)
{
if (command == Commands.MoveNorth) return position with { Y++ };
if (command == Commands.MoveSouth) return position with { Y-- };
if (command == Commands.MoveEast) return position with { X++ };
if (command == Commands.MoveWest) return position with { X-- };
return null;
}
public record Point(int X, int Y);
I'm trying to make new records using with statement, but it resulted in an error saying The name 'Y' does not exist in the current context Can anybody help explain? Thanks
28 Replies
Angius
Angius14mo ago
Try with { Y = Y + 1 } and so on?
EddieV
EddieV14mo ago
Did it, still get the same error
Pobiega
Pobiega14mo ago
ah, you can't do Y++ like that you need to do return position with { Y = position.Y + 1 }; also, this could (and should) be a switch expression
private Point? GetNewPosition(Commands command, Point position) =>
command switch
{
Commands.MoveNorth => position with { Y = position.Y + 1 },
Commands.MoveSouth => position with { Y = position.Y - 1 },
Commands.MoveEast => position with { X = position.X + 1 },
Commands.MoveWest => position with { X = position.X - 1 },
_ => null
};
private Point? GetNewPosition(Commands command, Point position) =>
command switch
{
Commands.MoveNorth => position with { Y = position.Y + 1 },
Commands.MoveSouth => position with { Y = position.Y - 1 },
Commands.MoveEast => position with { X = position.X + 1 },
Commands.MoveWest => position with { X = position.X - 1 },
_ => null
};
Point? is the correct returntype, since it might return null.
EddieV
EddieV14mo ago
Thanks @Pobiega . I changed the code as you suggested and it indeed worked!! And the switch statement looks so much nicer than my ifs 😂 Would you mind explaining why I couldn't use Y++ there?
Pobiega
Pobiega14mo ago
its just not possible to use increment decrement operators with with sadly its worth remembering that Y++ does two things - it both evaluates into a number, but also mutates the number thats probably why
EddieV
EddieV14mo ago
I see. Thank you. Just one more unrelated question about this
Point? is the correct returntype, since it might return null.
Pobiega
Pobiega14mo ago
nullable reference types ❤️
EddieV
EddieV14mo ago
Does it mean I should always put ? if any of my methods might return null?
Pobiega
Pobiega14mo ago
yep. in fact, what .net version are you using?
EddieV
EddieV14mo ago
6.0.402
Pobiega
Pobiega14mo ago
its a language feature added in .NET 5, and since 6.0 it defaults to enabled
EddieV
EddieV14mo ago
Ah, so it's not necessary for .NET >= 6?
Pobiega
Pobiega14mo ago
erm, rather, Im suprised your IDE isnt yelling at you
EddieV
EddieV14mo ago
I don't know 😂 I'm coming from Python and C# is still fairly new to me! Anyway, thanks for your help. Really appreciate it! 😄
Pobiega
Pobiega14mo ago
Nullable reference types - C# reference
Learn about C# nullable reference types and how to use them
Pobiega
Pobiega14mo ago
the idea is that any reference type can ofc be null but that ability often causes issues during runtime its annoying having to nullcheck things in every single method so the idea was, "what if we add a way to document if a method can or can't return null" consider these two methods
private Point? GetNewPosition(Commands command, Point position) =>
command switch
{
Commands.MoveNorth => position with { Y = position.Y + 1 },
Commands.MoveSouth => position with { Y = position.Y - 1 },
Commands.MoveEast => position with { X = position.X + 1 },
Commands.MoveWest => position with { X = position.X - 1 },
_ => null
};


private Point GetNewPosition(Commands command, Point position) =>
command switch
{
Commands.MoveNorth => position with { Y = position.Y + 1 },
Commands.MoveSouth => position with { Y = position.Y - 1 },
Commands.MoveEast => position with { X = position.X + 1 },
Commands.MoveWest => position with { X = position.X - 1 },
_ => position
};
private Point? GetNewPosition(Commands command, Point position) =>
command switch
{
Commands.MoveNorth => position with { Y = position.Y + 1 },
Commands.MoveSouth => position with { Y = position.Y - 1 },
Commands.MoveEast => position with { X = position.X + 1 },
Commands.MoveWest => position with { X = position.X - 1 },
_ => null
};


private Point GetNewPosition(Commands command, Point position) =>
command switch
{
Commands.MoveNorth => position with { Y = position.Y + 1 },
Commands.MoveSouth => position with { Y = position.Y - 1 },
Commands.MoveEast => position with { X = position.X + 1 },
Commands.MoveWest => position with { X = position.X - 1 },
_ => position
};
the bottom one can never return null but the top one can, so we add a ? to the return type to document that this will give us warnings if we try to use that value without checking it for null to prevent NullRefExceptions at runtime 🙂
EddieV
EddieV14mo ago
Let me read the documentation a bit more Thank you for the useful info
Pobiega
Pobiega14mo ago
yw
EddieV
EddieV14mo ago
Now I noticed it, the IDE did yell at me via these lines
EddieV
EddieV14mo ago
I tried to put ? to where appropriate and the warnings left one by one except here return new FountainOfObjects(name); and here SendMessage(message); my SendMessage returns void
Pobiega
Pobiega14mo ago
yeah but message might be null, and SendMessage probably doesnt take message? so it wants you to make sure message is not null before passing it into SendMessage
EddieV
EddieV14mo ago
I think I did? string? message = _world.GetMessage(_player.Position);
Pobiega
Pobiega14mo ago
well, not really you've stored it in a variable that says "this might be null" you have not actually CHECKED if it is null or not
EddieV
EddieV14mo ago
Ah I see I checked for null within the SendMessage method instead of checking before sending it to the method
Pobiega
Pobiega14mo ago
thats fine, but then your method could either accept string? or you move the check out 🙂
EddieV
EddieV14mo ago
Yeah, I moved the check out and managed to get rid off the warning of null at the method to instantiate a new object too. You're right, it could get a bit of annoying 😂 No more yellowy warning!! Thanks very much for your help
Pobiega
Pobiega14mo ago
np
Accord
Accord14mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.