我尝试实现以下目标:我有一个名为IAxis的interace强制我的类TheAxis拥有某些方法。另外我想基于参数实现某种抽象类。要解释这一点,请将其写在代码中:
class TheAxis : IAxis
{
public TheAxis(){ }
public void IMoveToPos(int pos) {} //This is forced by the Interface
}
当调用此类的实例时,它应该能够选择要包含的方法,类似于虚方法但不覆盖现有方法,但是添加来自另一个类的已编码方法。我正在寻找这样的东西:
abstract class GateAxis
{
public void CloseGate() { IMoveToPos(0); }
}
abstract class XAxis
{
public void MoveToStart() { IMoveToPos(100); }
}
TheGateAxis = new Axis() as GateAxis;
现在我希望能够使用TheGateAxis.Closegate();但不是TheGateAxis.MoveToStart();
如果我打电话
TheXAxis = new Axis() as XAxis;
我希望能够使用TheXAxis.MoveToStart();但不是TheXAxis.CloseGate();
XAxis或GateAx中给出的方法不需要TheAxis中的任何方法,除了接口给出的onces。
有可能做那样的事吗?根据实例化类时给出的参数将类添加到类中?
我希望你得到我想做的事情,因为我很难解释。
最佳, 凯文
答案 0 :(得分:1)
// super class
abstract class TheAxis : IAxis {
public TheAxis() { }
public void IMoveToPos(int pos) { } //This is forced by the Interface
}
abstract class GateAxis : TheAxis {
public virtual void CloseGate() { IMoveToPos(0); }
}
abstract class XAxis : TheAxis {
public virtual void MoveToStart() { IMoveToPos(100); }
}
现在,如果从GateAxis
派生一个类,它只能访问GateAxis
中的接口方法和方法。同样适用于TheAxis
。
答案 1 :(得分:1)
好吧,如果你想让类从基类共享很少的方法,而其他方法是分开的,你可以做
//an interface (optional)
public interface IAxis {
void MoveToPos(int pos);
}
public abstract class AxisBase : IAxis {
public void MoveToPos(int pos) {
//implementation
}
}
//optionally you can do an IGateAxis interface, inheriting (or not) from IAxis
public interface IGateAxis : IAxis {
void CloseGate();
}
//classes inheriting from AxisBase, implementing IGateAxis
public class GateAxis : AxisBase, IGateAxis {
public void CloseGate() {
MoveToPos(0);
}
}
//another interface, not inheriting from IAxis
public interface IXAxis {
void MoveToStart();
}
//another class inheriting from AxisBase
public class XAxis : AxisBase, IXAxis {
public void MoveToStart() {
MoveToPos(100);
}
}
使用
var gateAxis = new GateAxis();
gateAxis.CloseGate();
//and you can do
gateAxis.MoveToPos(250);
var xAxis = new XAxis();
xAxis.MoveToStart();
//and you can do
xAxis.MoveToPos(40);
使用IGateAxis界面
IGateAxis gateAxis = new GateAxis();
gateAxis.CloseGate();
gateAxis.MoveToPos(1);
使用IXAxis界面
IXAxis xAxis = new XAxis();
gateAxis.MoveToStart();
//but you can't do
//gateAxis.MoveToPos(10);
//as IXAxis doesn't know about this method.
答案 2 :(得分:0)
动态添加方法,删除这些方法不是您可以在“普通”C#
中执行的操作。没有任何OOP模式可以模拟这个。
可以做什么,正在使用ExpandoObject来实现完全您要实现的目标。
表示可以动态添加成员的对象 在运行时删除。
顺便说一下,我不鼓励你使用它,因为你处于静态类型的语言域,所以可能是一个很好的想法,一点点修改你的架构,不要跳进动态语言使用C#
的域名。
答案 3 :(得分:0)
我认为解决这个问题的最佳方法是使用接口和单个(基础)类。
public interface IAxis {
void MoveToPos(int pos);
}
public interface IGateAxis {
void CloseGate();
}
public interface IXAxis {
void MoveToStart();
}
public class TheAxis : IAxis, IGateAxis, IXAxis {
public TheAxis(){ }
void IAxis.MoveToPos(int pos) {}
void IGateAxis.CloseGate() { ((IAxis)this).MoveToPos(0); }
void IXAxis.MoveToStart() { ((IAxis)this).MoveToPos(100); }
}
IGateAxis gateAxis = new ThisAxis();
gateAxis.CloseGate();
IXAxis xAxis = new ThisAxis();
xAxis.MoveToStart();
这样,您可以指定某些类型的轴可用的方法。此外,您可以通过工厂模式或甚至单个静态方法强制创建轴,以便于创建轴。
答案 4 :(得分:0)
假设您有超过3种方法,我看到的最简单的方法就是创建一个充当责任链的代理:
public class AxisProxy : IAxis
{
public AxisProxy(params IAxis[] implementations) {
this.implementations = implementations;
}
private IAxis[] implementations;
public virtual void CloseGate()
{
foreach (var item in implementations)
{
try { item.CloseGate(); } catch (NotSupportedException) {}
}
throw new NotSupportedException();
}
public virtual void MoveToStart()
{
foreach (var item in implementations)
{
try { item.MoveToStart(); } catch (NotSupportedException) {}
}
throw new NotSupportedException();
}
}
您可以创建Axis的基本实现,以确保所有默认实现都抛出异常。派生的实现实现了特定的功能。
然后您只需拨打
即可使用它IAxis myAxis = new AxisProxy(new GateAxis(), new XAxis());
注意:在这种情况下,我会认真考虑将类型更改为'bool';如果你经常调用这些方法,异常性能会加起来...而且,由于NotSupportedException不会改变,你可以保留每个方法列表来删除抛出的实现。