我正在尝试重现某些WinForms控件(例如DataGridView
和DataGridViewColumn
)中的行为,其中子对象具有指向父对象的属性。此属性通常是只读的,但在调用父Add()
方法之后会以某种方式更改。
在我的代码中,我有两个类DataGroup
和DataEntry
,后者是子对象。
如果我只是实现了以下内容:
public class DataEntry
{
public DataGroup Parent { get; set; }
}
public class DataGroup
{
public List<DataEntry> DataEntries { get; set; }
public DataGroup()
{
DataEntries = new List<DataEntry>();
}
public void Add(DataEntry de)
{
// Check stuff here
// ...
//
DataEntries.Add(de);
de.Parent = this;
}
}
它确实有效,但有一个主要缺点:DataEntry.Parent
有一个公共设置器,所以可以在任何地方修改属性,而不需要我在DataGroup.Add()
我可以做以下事情:
public class DataEntry
{
private DataGroup _parent;
public DataGroup Parent
{
get { return _parent; }
set
{
_parent = value;
_parent.Add(this);
}
}
}
public class DataGroup
{
...
public void Add(DataEntry de)
{
// Check stuff here
// ...
//
_dataEntries.Add(de);
// de.Parent = this; Already set!
}
...
}
如果我想通过设置其父属性来添加子项,则可以正常工作,但如果我调用DataEntry.Parent
DataGroup.Add()
正如我已经说过的,WinForms控件不能直接在子节点中更改Parent属性是很正常的,但是在从父节点调用Add方法后更改属性。 我无法找出链接,父母修改子属性的方法,除非该属性是公共的或通过方法公开,这两种方法都有机会绕过我的检查并最终产生错误
答案 0 :(得分:0)
如果您只是想从外部方隐藏方法,您可以声明方法内部
internal void SetParent(DataGroup dg)
{
//code to set parent
}
我从来没有尝试过这个,但它也可能有效。我一直都是私下做的。
public DataGroup Parent { get; internal set; }
另一个隐藏自己的选择是使用显式接口实现。甚至将它与内部结合以将其从外部隐藏起来。当您显式实现接口时,调用该方法的唯一方法是首先将对象强制转换为接口。我觉得这样的事情会起作用
internal interface ISetParent
{
void SetParent(DataGroup dg);
}
public class DataEntry : ISetParent
{
void ISetParent.SetParent(DataGroup dg)
{
Parent = dg;
}
public DataGroup Parent { get; private set;}
}
public class DataGroup
{
public List<DataEntry> DataEntries { get; set; }
public DataGroup()
{
DataEntries = new List<DataEntry>();
}
public void Add(DataEntry de)
{
// Check stuff here
// ...
//
DataEntries.Add(de);
((ISetParent)de).SetParent(this);
}
}