4

私は次のクラスを持っています:

public abstract class CommonEvents : DisposableObject
{
    /// <summary>
    /// Internal method for storing error messages to our event
    /// </summary>
    /// <param name="message"></param>
    /// <param name="showException"></param>
    /// <param name="exception"></param>
    public void OnError(string message, OnErrorEventsArgs.ShowExceptionLevel showException, Exception exception)
    {
        if (_onErrorEvent == null) return;

        var e = new OnErrorEventsArgs(message, showException, exception);

        _onErrorEvent(this, e);
    }

    /// <summary>
    /// Internal event handler allowing for logging of events within the class
    /// </summary>
    private EventHandler<OnErrorEventsArgs> _onErrorEvent;

    /// <summary>
    /// Public event handler allowing for accessibility outside of the class
    /// </summary>
    public event EventHandler<OnErrorEventsArgs> OnErrorEvent
    {
        add { _onErrorEvent += value; }
        remove { _onErrorEvent += value; }
    }
}

そして、私は自分のプロジェクトの1つでそれを継承しようとしていますが、すでに別のクラスを継承しています.コードは以下のとおりです:

public class ItemDal : Common.Dal.BaseDal, CommonEvents
{

私が受け取っているエラーは

「CommonEvents」: インターフェイス名が必要です

これを調査したとき、インターフェースを構築しようとしましたが、これを達成するのに十分な理解が得られなかったため、不足しました。これを理解するのを手伝ってくれますか、それとも良い記事の方向性を教えてくれませんか?

4

4 に答える 4

6

そして、私は自分のプロジェクトの1つでそれを継承しようとしていますが、すでに別のクラスを継承しています

これは、C# が多重継承をサポートしていないことをコンパイラが伝える方法です。クラスをベースのリストに入れる場合、残りの名前はインターフェイスを参照する必要があります。

2 つのクラスを継承できるのは、一方が他方を直接的または間接的に継承する場合のみです。このようにして、最も派生したクラスを、たまたまそのベースになっている他のクラスと共に継承します。

C# での一般的な解決策は、クラスの 1 つからインターフェイスを抽出し、実装のインスタンスを埋め込み、コンポジションによってクラスに含まれる実装にインターフェイス呼び出しを転送することです。

あなたの場合、次のようになります。

interface ICommonEvents {
    void OnError(string message, OnErrorEventsArgs.ShowExceptionLevel showException, Exception exception);
    event EventHandler<OnErrorEventsArgs> OnErrorEvent {add;remove;}
}
// Keep the implementation the same
public class CommonEvents : DisposanbleObject, ICommonEvents {
    ...
}
// Here is your derived class:
public class ItemDal : Common.Dal.BaseDal, ICommonEvents {
    private readonly CommonEvents ce = ... // Initialize your common events
    void OnError(string message, OnErrorEventsArgs.ShowExceptionLevel showException, Exception exception) {
        ce.OnError(message, showException, exception);
    }
    event EventHandler<OnErrorEventsArgs> OnErrorEvent {
        add {ce.OnErrorEvent += value;}
        remove {ce.OnErrorEvent -= value;}
    }
}
于 2013-10-04T01:15:40.097 に答える
2

CommonEvents はインターフェースではなく、抽象クラスです。インターフェースはコンパイラーが予期していたものですが、抽象クラスは継承する必要があります。違いについてはこちらに書いてあります。抽象クラスをインターフェイスに変更して、コードを親クラスに入れるだけでよいでしょうか? このような

public interface class ICommonEvents 
{
    /// <summary>
    /// Internal method for storing error messages to our event
    /// </summary>
    /// <param name="message"></param>
    /// <param name="showException"></param>
    /// <param name="exception"></param>
    public void OnError(string message, OnErrorEventsArgs.ShowExceptionLevel showException, Exception exception);

    /// <summary>
    /// Internal event handler allowing for logging of events within the class
    /// </summary>
    private EventHandler<OnErrorEventsArgs> _onErrorEvent;

    /// <summary>
    /// Public event handler allowing for accessibility outside of the class
    /// </summary>
    public event EventHandler<OnErrorEventsArgs> OnErrorEvent;
}

public class CommonEvents : DisposableObject, ICommonEvents
{
    /// <summary>
    /// Internal method for storing error messages to our event
    /// </summary>
    /// <param name="message"></param>
    /// <param name="showException"></param>
    /// <param name="exception"></param>
    public void OnError(string message, OnErrorEventsArgs.ShowExceptionLevel showException, Exception exception)
    {
        if (_onErrorEvent == null) return;

        var e = new OnErrorEventsArgs(message, showException, exception);

        _onErrorEvent(this, e);
    }

    /// <summary>
    /// Internal event handler allowing for logging of events within the class
    /// </summary>
    private EventHandler<OnErrorEventsArgs> _onErrorEvent;

    /// <summary>
    /// Public event handler allowing for accessibility outside of the class
    /// </summary>
    public event EventHandler<OnErrorEventsArgs> OnErrorEvent
    {
        add { _onErrorEvent += value; }
        remove { _onErrorEvent += value; }
    }
}

public class ItemDal : CommonEvents
{ ...
于 2013-10-04T01:27:29.960 に答える
2

C# では、aclassは互いに 1 つしか継承できませんclass(ただし、そのクラスは別のクラスから継承することもできます)。

classの後に続くもの:はすべてインターフェイスでなければならないため、コンパイラは であると想定CommonEventsしていますinterfaceが、そうではありません。

ここでは、すぐに利用できる 2 つのアプローチがあります。

  1. 継承Common.Dal.BaseDalする必要がありますCommonEvents(したがって、"through"ItemDalを継承します。CommonEventsCommon.Dal.BaseDal
  2. 内でクラスの 1 つを使用しますItemDal。したがってItemDal、メソッドに似たメンバーを公開する可能性がありますが、すべてのロジックを含むコンポーネントを呼び出します。これはコンポジションとして知られています。
于 2013-10-04T01:19:35.160 に答える
2

複数のクラスから継承することはできませんが、クラスとインターフェイスから継承することはできます

C# ではいくつのクラスから継承できますか?

インターフェイスは基本的にコントラクトです。コントラクトを実装するには具象クラスが必要です。

B: A 、 C: B などの継承をチェーンするか、次のように CommonEvents のインターフェイスを作成する必要があります。

 public interface ICommonEvents
{
    void BroadcastMessage(string text);
}

public class CommonEvents : ICommonEvents
{
    public void BroadcastMessage(string text)
    {

    }
}

これで、インターフェイスを実装し、具象クラス CommonEvents を依存関係として取得し、メソッドをそれに委譲できます。

public class ItemDal : Common.Dal.BaseDal, ICommonEvents
{
    private readonly CommonEvents _commonEvents;

    public ItemDal(CommonEvents commonEvents)
    {
        _commonEvents = commonEvents;
    }

    #region Implementation of ICommonEvents

    void ICommonEvents.BroadcastMessage(string text)
    {
        _commonEvents.BroadcastMessage(text);
    }

    #endregion
}

これを行う前に、本当にそれを行う必要がある場合は、設計を検討することをお勧めします。これは、おそらく単一責任の原則 ( https://en.wikipedia.org/wiki/Single_responsibility_principle ) に違反するためです。DAL クラスはエラー処理を行うべきではありません

于 2013-10-04T01:20:30.420 に答える