【问题标题】:how to use constructor injection with abstract class?如何将构造函数注入与抽象类一起使用?
【发布时间】:2012-11-02 17:15:25
【问题描述】:

我一直在尝试学习依赖注入,但运行代码时出现 2 个错误:

  1. DependencyInjection.Message.Sms() 必须声明一个主体,因为它没有标记为抽象、外部或部分。
  2. 无法将类型DependencyInjection.IInterface 隐式转换为DependencyInjection.MyClass。存在显式转换(您是否缺少演员表?)

下面的代码对 DI 来说是一个好的设计吗?

namespace DependencyInjection
{
    public interface IInterface
    {

    }

    public abstract class Message
    {
        public virtual void Sms();
    }

    public class MyClass : Message, IInterface
    {
        public override void Sms()
        {
            Console.WriteLine("Sms gönder.");
        }
    }

    public class ClassManager
    {
        private IInterface _myinterface;


        public MyClass Xyz
        {
            get { return _myinterface; }
            set { _myinterface = value; }
        }

        public ClassManager(IInterface myinterface)
        {
            _myinterface = myinterface;
        }
    }
}

【问题讨论】:

  • 你是想学习依赖注入,还是只是学习写 C#?

标签: c# .net oop design-patterns dependency-injection


【解决方案1】:

改变这个

public abstract class Message
{
    public virtual void Sms();
}

到这里

public abstract class Message
{
    public abstract void Sms();
}

你要么给虚方法一个主体,像这样

public virtual void Sms() { }

或者你把它标记为抽象

public abstract void Sms();

编辑:

忘记了第二个错误。改变这个

public MyClass Xyz
    {
        get { return _myinterface; }
        set { _myinterface = value; }
    }

到这里

public IInterface Xyz
    {
        get { return _myinterface; }
        set { _myinterface = value; }
    }

【讨论】:

  • 编辑了我的答案。对此感到抱歉:)
  • 我可以使用它: public ClassManager(IInterface myinterface) : ClassManager mngr = new ClassManager( new MyClass());但我不能:public MyClass Xyz { get { return _myinterface; } 设置 { _myinterface = 值; } }
  • 如我所说:将Xyz的属性类型从MyClass改为IInterface
【解决方案2】:

1) DependencyInjection.Message.Sms()' 必须声明一个主体,因为它没有标记为抽象、外部或部分

在方法声明中添加 abstract 关键字(并删除虚拟):

public abstract void Sms();

2) 无法将类型“DependencyInjection.IInterface”隐式转换为“DependencyInjection.MyClass”。存在显式转换(您是否缺少演员表?)

private IInterface _myinterface;
public MyClass Xyz
{
    get { return _myinterface; }
    set { _myinterface = value; }
}

Xyz 的返回类型为 MyClass,但在 get 中,您返回的 _myinterface 类型为 IInterface

更改如下:

public IInterface Xyz
{
    get { return _myinterface; }
    set { _myinterface = value; }
}

【讨论】:

    【解决方案3】:
    1. 您正在声明一个没有主体的虚拟方法。虚拟方法必须声明一个主体,该主体将作为该方法的默认实现。您可以将您的方法声明为abstract,这意味着派生类必须提供自己的实现:

      public abstract void Sms();
      

      或者您可以保持方法为虚拟并在基类中提供默认实现:

      public virtual void Sms()
      {
          // Default or no implementation goes here.
      }
      
    2. 在以下代码中,您尝试将 IInterface 转换为 MyClass,这可能不是您想要的。

      public MyClass Xyz
      {
          get { return _myinterface; }
          set { _myinterface = value; }
      }
      

      您可能希望返回 IInterface

      public IInterface Xyz
      {
          get { return _myinterface; }
          set { _myinterface = value; }
      }
      

    【讨论】:

      猜你喜欢
      • 2019-04-02
      • 1970-01-01
      • 2020-10-04
      • 2015-06-18
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2011-04-02
      相关资源
      最近更新 更多