只是想知道解决这种情况的推荐方法是什么,为什么它是一种更好的方法。
比方说,您有一个代表足球队的班级,您可能有类似的东西(当然是简化的版本):
public class FootballTeam
{
public FootballTeam(string name, Person owner)
{
Name = name;
Owner = owner;
}
public string Name {get;}
public Person Trainer {get; set;}
public Person Owner {get; set;}
public List<Person> Roster {get; set;}
}
现在,我们可以争辩说,即使一个没有球员的球队仍然有一个名册,只是一个空的名册(与不存在的名册相对)。
因此,像这样声明Roster
可能更有意义:
public List<Person> Roster {get; set;} = new List<Person>();
但是我认为这仍然存在问题:
由于Roster
仍然有一个二传手,因此它无济于事,无法防止将其设置为null
,这也很容易错误地假定为永远null
。
因此Roster
应该看起来像这样:
public List<Person> Roster {get;} = new List<Person>();
因此,从某种意义上说,从某种意义上说,从某种意义上说,团队总是有一个名册,只是有时名册上没有任何球员。而且我们从某种意义上简化了调用方的事情,因为他们不必担心空引用。
但是这样做的话,我们失去了用现有的花名册轻松替换现有完整花名册的能力,因此,我们必须绑定到必须从中添加/删除/清除Persons
的实例有两支具有相同球员的球队,检查他们的Rosters
是否相等,将返回false
,依此类推。
有几个问题:
解决此问题的最佳方法是什么?隐藏List<Person>
并提出与之间接交互的转发方法似乎是过分的,几乎没有任何好处。删除设置器会删除一些简单性和功能性,让Roster
成为null
对我来说似乎更糟。
假定对1.的回答涉及为Roster
属性分配默认值,那么在哪里执行此操作是否有最佳实践?即直接在上面示例中的属性或构造函数上?
您还可以争辩说,团队也必须始终具有Owner
,尽管不一定必须始终具有Trainer
。您将如何处理呢?转发方法还是检查设置器上的value == null
是否throw
?
答案 0 :(得分:0)
如果团队“拥有”列表,我希望看到这样的东西:
public class FootballTeam
{
private readonly List<Person> _roster = new List<Person>();
public FootballTeam(string name, Person owner)
{
Name = name;
Owner = owner;
}
public string Name {get;}
public Person Trainer {get; set;}
public Person Owner {get; set;}
public IEnumerable<Person> Roster => _roster.AsReadOnly();
public void AddPlayer(Person player) {
_roster.Add(player);
//Other logic
}
public void RemovePlayer(Person player) {
//What if the player isn't on our roster?
//Other logic?
_roster.Remove(player);
}
public void ReplaceRoster(IEnumerable<Person> players) {
_roster.Clear();
_roster.AddRange(players);
}
}
我通常不会添加ReplaceRoster
方法,但是显然这是您的用例之一。请注意,我们现在使用的是List
封装的,并且我们在类支持的方法中将 up 移到了语义级别。>
我们类中的其他方法可以依靠_roster
为非空。即使花名册为空,我们班的消费者也始终可以依靠获得IEnumerable<Person>
。
如果团队不“拥有”这份名单,我不希望它完全拥有这份财产。
答案 1 :(得分:0)
尝试一下:
private List<Person> _roster = new List<Person>();
public List<Person> Roster {get=>_roster; set=>_roster = value ?? new List<Person>();}
这将防止为_roster分配空值。