接口后面的C#类,包含abstract的方法

时间:2013-01-15 08:23:07

标签: c# .net interface abstract

我尝试实现以下目标:我有一个名为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。

有可能做那样的事吗?根据实例化类时给出的参数将类添加到类中?

我希望你得到我想做的事情,因为我很难解释。

最佳, 凯文

5 个答案:

答案 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不会改变,你可以保留每个方法列表来删除抛出的实现。