在我当前的项目中,我需要能够同时拥有类的可编辑和只读版本。因此,当类显示在 List 或 PropertGrid 中时,用户无法编辑他们不应被允许的对象。
为此,我遵循下图中所示的设计模式。我从一个只读接口(interface) (IWidget
) 开始,然后创建一个实现此接口(interface) (Widget
) 的可编辑类。接下来,我创建了一个只读类 (ReadOnlyWidget
),它简单地包装了可变类并实现了只读接口(interface)。
对于许多不同的不相关类型,我都遵循这种模式。但现在我想在我的程序中添加一个搜索功能,它可以生成包含各种类型的结果,包括可变和不可变版本。所以现在我想添加另一组接口(interface)(IItem
、IMutableItem
)来定义适用于所有类型的属性。因此 IItem
定义了一组通用的不可变属性,而 IMutableItem
定义了相同的属性但可编辑。最后,搜索将返回 IItems
的集合,如果需要,稍后可以将其转换为更具体的类型。
但是,我不确定我是否正确地设置了与 IMutable
和 IItem
的关系。现在我有每个接口(interface)(IWidget
、IDooHickey
)继承自 IItem
,然后是可变类(Widget
, DooHickey
) 此外还实现了 IMutableItem
。
或者,我也在想我可以设置 IMutableItem
继承自 IItem
,这将使用具有 get 和 set 的新属性隐藏它的只读属性访问器。然后可变类将实现 IMutableItem
,而只读类将实现 IItem
。
如有任何建议或批评,我将不胜感激。
类图
代码
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/