我有一个班级:
public class A
{
private IB link;
public IB Link
{
get { return link; }
set
{
link = value;
b.Link = this;
}
}
...
}
和界面:
public interface IB
{
A Link { get; set; }
}
我将这样使用它:
public class B1 : IB, Button
{
public A Link { get; set; }
...
}
public class B2 : IB, TextBox
{
public A Link { get; set; }
...
}
b1 = new B1();
b2 = new B2();
A a = new A();
a.Link = b1;
...
a.Link = b2;
但我必须封装IB.Link
属性,它只应在A
类(以及A.Link
属性)中更改。这可能吗?
更新
很抱歉这个例子含糊不清。我的真实代码太大而没有完成:我有一个节点结构。每个节点都有一个指向Control的链接。因此,可以构建控件的视觉结构。我们可以从节点管理控件,但不能从控件访问节点,例如,从OnMouseClick方法。我们需要有后引用 - IMyControl.OwnerNode属性。 IMyControl是仅包含此属性的接口。因此,我们可以创建“MyControl:IMyControl,Control”类并在其中实现鼠标单击逻辑。当我们将控制分配给节点时,必须创建,直接和返回两个引用,但它发生在节点类的代码中,而不是在MyControl和IMyControl代码中。 IMyControl接口中的属性字段必须可以从NodeClass写入,并且无法访问派生类的写入。我想在这里完成。
答案 0 :(得分:1)
如果我理解正确,您可以使用此草稿:
class Node
{
public ControlWrapper Link { get; set; }
}
abstract class ControlWrapper
{
private readonly Node _node;
private readonly Control _control;
public Node Node
{
get { return _node; }
}
public Control Control
{
get { return _control; }
}
public ControlWrapper(Node node, Control control)
{
if (node == null)
throw new ArgumentNullException("node");
if (control == null)
throw new ArgumentNullException("control");
_node = node;
_control = control;
}
}
class ControlWrapper<TControl> : ControlWrapper
where TControl : System.Windows.Forms.Control
{
public TControl Control
{
get { return (TControl)base.Control; }
}
public ControlWrapper(Node node, TControl control)
: base (node, control)
{
}
}
class Program
{
static void Main(string[] args)
{
Node n1 = new Node();
n1.Link = new ControlWrapper<TextBox>(n1, new TextBox());
Node n2 = new Node();
n2.Link = new ControlWrapper<Button>(n2, new Button());
}
}
抽象类ControlWrapper为您提供了到节点的反向链接(您无法在接口中封装逻辑,因此抽象类在这里),类型派生泛型类提供了用于创建控件包装器的实际实现的构造函数。
如果您希望此关系自动强制其一致性,您应该编写如下代码:
class Program
{
static void Main(string[] args)
{
Node n1 = new Node();
n1.SetControl(new TextBox());
Node n2 = new Node();
n2.SetControl(new Button());
}
}
class Node
{
private ControlWrapper _link;
public ControlWrapper Link
{
get { return _link; }
}
public void SetControl<TControl>(TControl control)
where TControl : System.Windows.Forms.Control
{
ControlWrapper prevLink = Link;
if (prevLink != null)
prevLink.Dispose();
_link = new ControlWrapper<TControl>(this, control);
}
}
// microsoft basic dispose pattern
// http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx#basic_pattern
abstract class ControlWrapper : IDisposable
{
private readonly Node _node;
private readonly Control _control;
public Node Node
{
get { return _node; }
}
public Control Control
{
get { return _control; }
}
public ControlWrapper(Node node, Control control)
{
if (node == null)
throw new ArgumentNullException("node");
if (control == null)
throw new ArgumentNullException("control");
_node = node;
_control = control;
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_control != null)
_control.Dispose();
}
}
}
class ControlWrapper<TControl> : ControlWrapper
where TControl : System.Windows.Forms.Control
{
public TControl Control
{
get { return (TControl)base.Control; }
}
public ControlWrapper(Node node, TControl control)
: base (node, control)
{
}
}