I have a class player and player has a list of Shots. Each shot has its own yPos (position) because yPos of the player can change but shot will keep his position:
class Player
{
public string Id { set; get; }
public int yPos { set; get; }
public List<Shot> shots;
public Player(string _Id, int _yPos)
{
Id = _Id;
yPos = _yPos;
}
}
class Shot
{
public int yPos { set; get; }
public Shot(int _yPos)
{
yPos = _yPos;
}
}
Then at some point in the game a have id, and I need to find player. and add to list of his shots a new shot with that's players position.
Here is what I ended up with:
string tempID = "xxx"; // not important where this temp id is coming from
players.Find(p => p.Id == tempID).shots.Add(new Shot(players.Find(p => p.Id == tempID).yPos));
And seems to be fine but looks supper strange. is there a way to simplify this statement so I wouldn't have to look up for the same player twice in one statement?
4 Answers 4
I would at least cache your player result:
var player = players.Find(p => p.Id == tempId);
player.shots.Add(new Shot(player.yPos));
3 Comments
Instead of reaching into the Player to pull out its yPos value and creating a new Shot with it, and then shoving that Shot into the Player's Shot collection (how rude!), you could simplify things a bit by giving your Player a bit more smarts:
class Player
{
public string Id { set; get; }
public int yPos { set; get; }
public List<Shot> shots;
public Player(string _Id, int _yPos)
{
Id = _Id;
yPos = _yPos;
}
public void AddShotToYPos()
{
shots.Add(new Shot(yPos));
}
}
Then you could say:
players.Find(p => p.Id == tempID).AddShotToYPos();
1 Comment
At the risk of possibly stating something obvious, this would do one less lookup, and is possibly more readable:
string tempID = "xxx";
var player = players.Find(p => p.Id == tempID);
player.shots.Add(new Shot(player.yPos));
Comments
KISS:
var p = players.Find(p => p.Id == tempID);
p.shots.Add(new Shot(p.yPos));
Pointlessly long LINQ:
(from p in players
where p.Id == tempID
select p).Take(1).ToList().ForEach(p => p.shots.Add(new Shot(p.yPos)));
Nice and Short Extension:
players.Find(p => p.Id == tempID).Shoot();
...
static class Extensions
{
public static void Shoot(this Player p)
{
p.shots.Add(new Shot(p.yPos));
}
}
Cooler Lambda
(from p in players
where p.Id == tempID
let x = new Func<bool>(() => { p.shots.Add(new Shot(p.yPos)); return true; })
select x()).First();
Player.SetCurrentShotLoc()method? As Walkerneo pointed out, they are not very readable and you have to know very well when to use them. Use them in appropriate querying situations, not for iterations.