在集合中设置只读属性的对象

3
我有一个与这个帖子相似的问题,我有一个类。
public class MyClass
{
    // other properties
    public bool IsDefault { get; internal set; }
}

我有一个定义了集合类的代码:

public class MyCollection : ICollection<MyClass>
{
    private List<MyClass> _itemList = new List<MyClass>();

    public void SetAsDefault(MyClass item)
    {
        // Make sure no other items are default.
        _itemList.ForEach(x => x.IsDefault = false);

        // Set specified item as default.
        _itemList.Find(x => x.Equals(item)).IsDefault = true;
    }
}

我希望只有在MyCollection中的单个项目被标记为默认项,同时还能够直接检查MyClass中是否存在特定实例作为默认项。将MyClass.IsDefault的setter标记为internal,开发人员无法在程序集外设置IsDefault。然而,在我的情况下,我想要避免错误地设置IsDefault属性的开发人员可以访问程序集内部,因此使用internal是不够的。
有没有什么巧妙的解决方案?我完全不知道...

1
你可以创建一个静态属性 public static MyClass DefaultInstance; 并设置它。这将使用当前的默认实例。 - Thorsten Dittmar
4
你正在施加一份相当弱的合同,只有一个项目可以成为默认项。此外,是否可以想象某个项目可能是一个集合的默认值,但不是另一个集合的默认值呢?这种情况下,将默认值作为集合属性存储可能更好。 - TheInnerLight
2
你想要一个类的全局默认实例吗?还是每个集合都有一个默认实例?如果是前者,那么你面临的问题不止一个。如果是后者,为什么不将该信息作为MyCollection的私有成员保留呢? - decPL
3
IsDefault信息的用例是什么?MyClass实例真的需要知道它是默认值吗? - Janne Matikainen
2
如果你不相信你的同事能够做好工作,那么你就有一个问题,这个问题不能通过编写正确的代码来解决;你不可信任的同事可以随时更改那个代码。如果你在团队中遇到了社交良好编码行为的问题,那么这是一个管理问题,而不是编码问题。建立更好的代码所有权、代码审查、相互尊重等文化。 - Eric Lippert
显示剩余5条评论
2个回答

1
我认为这很难做到完美。由于其他开发者可以在别处设置该属性,因此我会尝试解决问题。您可以移除Objects属性,并将其作为集合的一个属性。由于某人可以检索MyClass实例并随意设置它,因此您可以在MyCollection中添加一个方法来检查MyClass实例是否是该集合中的默认值。
否则我不知道如何真正禁止您想要的操作。

1
根据这个答案和我问题的许多好评论,我将把默认值存储在集合中。我最初想要能够查看手头的项目是否为默认值,如果只有一个MyCollection实例,那么这将起作用。然而,我不能排除未来会有多个实例,这使得在项目本身中存储属性毫无意义。如果将来我想在多个MyCollection实例之间维护一个公共默认项,我想我可以将该属性设置为静态的。 - Thomas Ravkilde

1
如果您想获取或设置特定集合的默认实例,则需要使用属性:
public MyClass Default { get; set; }

定义在MyCollection类中。

如果您想知道给定的MyClass实例是否是特定集合的默认值,则需要使用此方法:

public bool IsDefaultFor(MyCollection collection) {
    return collection.Default == this;
}

如果您需要将默认实例作为集合的成员,请在 Default 属性的 setter 和 Remove 方法中添加此断言。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接