C# lambda simplification
本文关键字:simplification lambda | 更新日期: 2023-09-27 18:23:53
我有一个职业玩家,玩家有一个射击列表。每次射门都有自己的yPos(位置),因为球员的yPos可以改变,但射门会保持他的位置:
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;
}
}
然后在游戏中的某个时刻,我有了id,我需要找到玩家。并在他的投篮列表中添加一个球员位置的新投篮
以下是我最终得到的:
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));
看起来很好,但晚餐看起来很奇怪。有没有办法简化这个语句,这样我就不必在一个语句中两次查找同一个玩家了?
我至少会缓存你的玩家结果:
var player = players.Find(p => p.Id == tempId);
player.shots.Add(new Shot(player.yPos));
你可以通过给你的玩家多一点智慧来简化事情,而不是进入玩家提取其yPos值并用它创建一个新的Shot,然后将该Shot推入玩家的Shot集合(多么粗鲁!):
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));
}
}
然后你可以说:
players.Find(p => p.Id == tempID).AddShotToYPos();
冒着可能陈述一些明显内容的风险,这将少做一次查找,而且可能更可读:
string tempID = "xxx";
var player = players.Find(p => p.Id == tempID);
player.shots.Add(new Shot(player.yPos));
KISS:
var p = players.Find(p => p.Id == tempID);
p.shots.Add(new Shot(p.yPos));
无意义的长LINQ:
(from p in players
where p.Id == tempID
select p).Take(1).ToList().ForEach(p => p.shots.Add(new Shot(p.yPos)));
漂亮而简短的扩展:
players.Find(p => p.Id == tempID).Shoot();
...
static class Extensions
{
public static void Shoot(this Player p)
{
p.shots.Add(new Shot(p.yPos));
}
}
冷却器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();