c# - C# 抽象类

标签 c#

我有一个界面

using ClassAbstractFactory;
public interface IPlugin
{
    AbstractFactory GetFactory();  
}

和一个 AbstractFactory

public abstract class AbstractFactory
{
    public abstract AbstractCake CreateCake();
    public abstract AbstractBox CreateBox();
}

public abstract class AbstractCake
{

    public abstract void Interact(AbstractBox box);

}

public abstract class AbstractBox
{

}

我有继承 AbstractCake 的 .dll

 public class ChocolateCake : AbstractCake
{

    private bool _isPacked;
    private bool _isDecorated;
    private string _nameOfCake;

    public ChocolateCake()
    {
        _isPacked = false;
        _isDecorated = false;
        _nameOfCake = "Шоколадный";
    }


   public bool IsPacked
   {
        get { return _isPacked; }
   }

    public bool IsDecorated
    {
        get { return _isDecorated; }

    }

    public string NameOfCake { get; set; }


    public override void Interact(AbstractBox box)
    {     
            _isPacked = true;       
    }


}

我像这样加载dll:

 public IPlugin LoadAssembly(string assemblyPath)
    {
        Assembly ptrAssembly = Assembly.LoadFile(assemblyPath);

        foreach (Type item in ptrAssembly.GetTypes())
        {
            if (!item.IsClass) continue;
            if (item.GetInterfaces().Contains(typeof(IPlugin)))
            {
                return (IPlugin)Activator.CreateInstance(item);
            }
        }
        throw new Exception("Invalid DLL, Interface not found!");
    }

        List<IPlugin> list = new List<IPlugin>();
        foreach (var assemblyPath in GetPathsListToDll())
        {
            list.Add(LoadAssembly(assemblyPath));
        }

如何访问 ChocolateCake 中的属性,以像使用它们

foreach (var str in list)
        {
            Boolean a = str.GetFactory().GetCake().CreateCake().IsPacked;
        }

或者像这样

string a = str.GetFactory().GetCake().CreateCake().NameOfCake;

或者像这样

str.GetFactory().GetCake().CreateCake().NameOfCake("Something");

或者像这样

str.GetFactory().GetCake().CreateCake().IsDecorated(true);

最佳答案

这里的问题是 AbstractFactory 有一个返回 AbstractCake 的方法,而 AbstractCake 本身根本没有属性。按照目前的情况,在访问 Cake 的任何属性之前,您需要将 Cake(直接或使用 as 关键字)向下转换为 ChocolateCake,这确实很困惑:

string a = (ChocolateCake)(str.GetFactory().CreateCake()).NameOfCake;

以下是一些注意事项:

  1. 将所有类型蛋糕共有的属性移至 AbstractCake 中,例如NameOfCakeIsPackedIsDecolated
  2. 鉴于 AbstractFactoryAbstractCake 类根本没有任何实现,请考虑将它们更改为接口(interface)而不是抽象类,即 ICakeFactory > 和ICake。具体实现将像以前一样是 ChocolateCakeFactoryChocolateCake
  3. 工厂和蛋糕的使用者现在应该只访问接口(interface)上公开的内容(ICakeFactoryICakeIBox),并且不需要进行任何向下转换或对 Cake 等的实际具体类型做出任何假设。

public interface ICake
{
    void Interact(IBox box);
    bool IsPacked { get; }
    bool IsDecorated { get; }
    string NameOfCake { get; set; }
}

public class ChocolateCake : ICake
{
    private bool _isPacked;
    private bool _isDecorated;
    private string _nameOfCake;

    public ChocolateCake() // ctor is not on the interface and is implementation detail
    {
        _isPacked = false;
        _isDecorated = false;
        _nameOfCake = "Шоколадный";
    }       

    public void Interact(IBox box) {...}
    public bool IsPacked { get { return _isPacked; } }
    public bool IsDecorated { get { return _isDecorated; } }
    // ...
}

public interface ICakeFactory
{
    ICake CreateCake();
    IBox CreateBox();
}

public class ChocolateCakeFactory : ICakeFactory
{
    public ICake CreateCake()   {return new ChocolateCake();}
    public IBox CreateBox() {return new ChocolateCakeBox();} 
}

回复:用法

您极不可能这样做:

string a = str.GetFactory().GetCake().CreateCake().NameOfCake;
str.GetFactory().GetCake().CreateCake().NameOfCake = "Something"; // Prop setter

因为这将每次创建一个新的蛋糕实例(并丢弃该实例)。怎么样:

class Bakery
{
   private readonly ICakeFactory _cakeFactory;
   public Bakery(ICakeFactory cakeFactory)
   {
       Contract.Requires(cakeFactory != null);
       cakeFactory = _cakeFactory;
   }

   bool BakeStuff()
   {
       var cake = _cakeFactory.CreateCake();
       cake.NameOfCake = "StackOverflow";
       return cake.IsDecorated && cake.IsPacked;
   }
}

编辑、重新引发更改事件

这涉及实现 INotifyPropertyChanged

public interface ICake : INotifyPropertyChanged

然后您可以在可变属性上筹集资金,例如

public string NameOfCake
{
    get { return _nameOfCake} ;
    set { 
        var propChanged = PropertyChanged;
        if (propChanged != null && value != _nameOfCake)
        {
            propChanged(this, new PropertyChangedEventArgs("NameOfCake"));
        }
        _nameOfCake = value;
    }
}

然后像这样订阅

var cake = new ChocolateCake();
cake.PropertyChanged += (sender, eventArgs) 
     => Console.WriteLine("Property {0} has changed", eventArgs.PropertyName);

关于c# - C# 抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29203267/

相关文章:

c# - 在对象名称中使用变量

c# - 这是什么意思 ?公共(public)名称{get;放;}

c# - 在 form_load 和 button_click 中调用函数有什么区别吗?

c# - C# 中分形 Perlin 噪声函数的均匀分布

c# - 为什么我在尝试在 Asp.NetCore 应用程序中包含对 UserServiceBaseLifetime() 的调用时遇到编译器错误?

c# - 使用正则表达式从字符串中获取值?

c# - 如何修复错误 "Cannot load PowerShell snap-in Microsoft.PowerShell.Diagnostics because of the following error: Could not load file or assembly"

c# - HashSet 不删除对象

c# - MVVM + 服务 + Entity Framework 和依赖注入(inject)与服务定位器

c# - 拖动时显示带有鼠标光标的图像缩略图