0

私は次のことを達成しようとしています。クラスTheAxisに特定のメソッドを強制するIAxisと呼ばれるインターレースがあります。さらに、パラメータに基づいて、ある種の抽象クラスを実装したいと思います。これを説明するために、コードでそれを書き留めます:

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
    // 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 に答える
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 に答える
0

メソッドを動的に追加し、それらを削除することは、「通常」でできることではありませんC#。これをシミュレートできるOOPパターンはありません。

あなたができることは、 ExpandoObjectを使用して、あなたが達成しようとしていることを正確に達成できるようにすることです。

実行時にメンバーを動的に追加および削除できるオブジェクトを表します。

ちなみに、静的型言語ドメインで使用することはお勧めしません。そのため、アーキテクチャを少し修正し、を使用して動的言語ドメインにジャンプしないことをお勧めしますC#

于 2013-01-15T08:30:45.407 に答える
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());

注:この場合、タイプを「bool」に変更することを真剣に検討します。これらのメソッドを頻繁に呼び出すと、例外のパフォーマンスが向上します...また、NotSupportedExceptionは変更されないため、メソッドごとのリストを保持して、スローされる実装を削除できます。

于 2013-01-15T08:55:24.583 に答える