类设计-属性默认值

时间:2019-03-13 08:45:45

标签: c# .net class

只是想知道解决这种情况的推荐方法是什么,为什么它是一种更好的方法。

比方说,您有一个代表足球队的班级,您可能有类似的东西(当然是简化的版本):

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,依此类推。

有几个问题:

  1. 解决此问题的最佳方法是什么?隐藏List<Person>并提出与之间接交互的转发方法似乎是过分的,几乎没有任何好处。删除设置器会删除一些简单性和功能性,让Roster成为null对我来说似乎更糟。

  2. 假定对1.的回答涉及为Roster属性分配默认值,那么在哪里执行此操作是否有最佳实践?即直接在上面示例中的属性或构造函数上?

  3. 您还可以争辩说,团队也必须始终具有Owner,尽管不一定必须始终具有Trainer。您将如何处理呢?转发方法还是检查设置器上的value == null是否throw

2 个答案:

答案 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分配空值。

相关问题