c# - 在复杂的对象结构中创建类的只读版本

标签 c# .net interface class-design readonly

在我当前的项目中,我需要能够同时拥有类的可编辑和只读版本。因此,当类显示在 List 或 PropertGrid 中时,用户无法编辑他们不应被允许的对象。

为此,我遵循下图中所示的设计模式。我从一个只读接口(interface) (IWidget) 开始,然后创建一个实现此接口(interface) (Widget) 的可编辑类。接下来,我创建了一个只读类 (ReadOnlyWidget),它简单地包装了可变类并实现了只读接口(interface)。

对于许多不同的不相关类型,我都遵循这种模式。但现在我想在我的程序中添加一个搜索功能,它可以生成包含各种类型的结果,包括可变和不可变版本。所以现在我想添加另一组接口(interface)(IItemIMutableItem)来定义适用于所有类型的属性。因此 IItem 定义了一组通用的不可变属性,而 IMutableItem 定义了相同的属性但可编辑。最后,搜索将返回 IItems 的集合,如果需要,稍后可以将其转换为更具体的类型。

但是,我不确定我是否正确地设置了与 IMutableIItem 的关系。现在我有每个接口(interface)(IWidgetIDooHickey)继承自 IItem,然后是可变类(Widget, DooHickey) 此外还实现了 IMutableItem

或者,我也在想我可以设置 IMutableItem 继承自 IItem,这将使用具有 get 和 set 的新属性隐藏它的只读属性访问器。然后可变类将实现 IMutableItem,而只读类将实现 IItem

如有任何建议或批评,我将不胜感激。

类图

alt text

代码

public interface IItem
{
    string ItemName { get; }
}

public interface IMutableItem
{
    string ItemName { get; set; }
}

public interface IWidget:IItem
{
    void Wiggle();
}

public abstract class Widget : IWidget, IMutableItem
{
    public string ItemName
    {
        get;
        set;
    }

    public void Wiggle()
    {
        //wiggle a little
    }
}

public class ReadOnlyWidget : IWidget
{
    private Widget _widget;
    public ReadOnlyWidget(Widget widget)
    {
        this._widget = widget;
    }

    public void Wiggle()
    {
        _widget.Wiggle();
    }

    public string ItemName
    {
        get {return  _widget.ItemName; }
    }
}

public interface IDoohickey:IItem
{
    void DoSomthing();
}


public abstract class Doohickey : IDoohickey, IMutableItem
{
    public void DoSomthing()
    {
        //work it, work it
    }

    public string ItemName
    {
        get;
        set;
    }
}

public class ReadOnlyDoohickey : IDoohickey
{
    private Doohickey _doohicky;
    public ReadOnlyDoohickey(Doohickey doohicky)
    {
        this._doohicky = doohicky;
    }

    public string ItemName
    {
        get { return _doohicky.ItemName; }
    }

    public void DoSomthing()
    {
        this._doohicky.DoSomthing();
    }
}

最佳答案

当您需要一个只读副本时,可以创建另一个对象吗?如果是这样,那么您可以在包含的代码中使用该技术。如果没有,我认为包装器可能是您最好的选择。

internal class Test
{
    private int _id;
    public virtual int ID
    {
        get
        {
            return _id;
        }
        set
        {
            if (ReadOnly)
            {
                throw new InvalidOperationException("Cannot set properties on a readonly instance.");
            }
        }
    }

    private string _name;
    public virtual string Name
    {
        get
        {
            return _name;
        }
        set
        {
            if (ReadOnly)
            {
                throw new InvalidOperationException("Cannot set properties on a readonly instance.");
            }
        }
    }

    public bool ReadOnly { get; private set; }

    public Test(int id = -1, string name = null)
        : this(id, name, false)
    { }

    private Test(int id, string name, bool readOnly)
    {
        ID = id;
        Name = name;
        ReadOnly = readOnly;
    }

    public Test AsReadOnly()
    {
        return new Test(ID, Name, true);
    }
}

关于c# - 在复杂的对象结构中创建类的只读版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3580706/

相关文章:

.net - 在 Visual Studio 中以部分信任的方式运行 MSTest

.net - 单一数据库记录的缓存方法

interface - TS Interface 不强制对实现者进行函数签名

c# - 转换 Select 以从集合中的 .Last() 获取属性

c# - C#中事件的内部设计

c# - 使用iText进行外部签名PDF

使用双泛型的 C# 类 : give only one when both of them should be the same?

c# - 如何创建返回实现接口(interface)的类的类型的方法的通用接口(interface)?

指定通用返回类型的 C# 接口(interface)

c# - Xamarin 表单工具栏项未显示在 View 中