期望的接口名称 - 但我不明白如何实现它

时间:2013-10-04 01:12:26

标签: c# interface

我有以下课程:

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; }
    }
}

我试图在我的一个项目中继承它,但是我已经在那里继承了另一个类,代码如下:

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

我收到的错误是

  

'CommonEvents':预期的接口名称

当我研究这个时,我试图构建一个接口 - 但后来发现很短,因为我不能理解这一点。能帮助我理解这一点,还是指点一篇好文章的方向来帮助我这样做?

4 个答案:

答案 0 :(得分:6)

  

我正试图在我的一个项目中继承它,但是我已经在那里继承了另一个类

这是编译器告诉你C#不支持多重继承的方式。如果将类放在基数列表中,则其余名称必须引用接口。

只有当其中一个类直接或间接地继承另一个类时,才能继承这两个类;这样你就可以继承最派生的类,以及恰好是其基础的另一个类。

C#中的一个常见解决方案是从其中一个类中提取接口,嵌入实现的实例,并通过合成将接口调用转发给类中包含的实现。

在你的情况下,它看起来像这样:

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;}
    }
}

答案 1 :(得分:2)

在C#中,class只能继承另一个class(尽管该类可能继承自另一个,依此类推)。

class之后:之后的任何内容必须是接口,因此编译器期望CommonEventsinterface,但它不是。{ / p>

这里有两种方法可供选择:

  1. Common.Dal.BaseDal继承CommonEvents(因此ItemDal会通过“CommonEvents继承Common.Dal.BaseDal”。
  2. ItemDal中使用您的一个班级。所以ItemDal可能会暴露与该方法类似的成员,但所有它都会调用包含所有逻辑的组件。这被称为组合。

答案 2 :(得分:2)

您不能从多个类继承,您可以通过

继承类和接口

How many classes can you inherit from in 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类不应该进行错误处理

答案 3 :(得分:2)

CommonEvents不是接口,它是一个抽象类。当接口是编译器期望的接口时,必须继承抽象类。 Here是关于差异的一篇文章。您可以将抽象类更改为接口并将代码放在父类中吗?喜欢这个

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
{ ...