0

我尝试实现以下目标:我有一个名为 IAxis 的接口,它强制我的类 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 或 GateAxis 中给出的方法不需要 TheAxis 中的任何方法,除了接口给出的一次。

有可能做这样的事情吗?根据实例化类时给定的参数向类添加方法?

我希望你能明白我正在努力做的事情,因为我很难解释。

最好的,凯文

4

5 回答 5

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.
于 2013-01-15T08:36:46.380 回答
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

于 2013-01-15T08:34:28.343 回答
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();

通过这种方式,您可以指定哪些方法可用于某些类型的轴。此外,您可以通过工厂模式甚至单个静态方法强制创建轴,以方便创建轴。

于 2013-01-15T08:36:36.030 回答
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());

注意:在这种情况下,我会认真考虑将类型更改为“布尔”;如果你经常调用这些方法,异常性能会增加......此外,由于 NotSupportedException 不会改变,你可以保留每个方法列表来删除抛出的实现。

于 2013-01-15T08:55:24.583 回答
0

动态添加删除方法不是您可以在 "normal" 中执行的操作C#。没有任何 OOP 模式可以模拟这一点。

可以做的是使用ExpandoObject来实现您想要实现的目标

表示一个对象,其成员可以在运行时动态添加和删除。

顺便说一句,我不鼓励在静态类型语言领域中使用它,所以稍微修改一下您的架构并且不要使用C#.

于 2013-01-15T08:30:45.407 回答