【问题标题】:How can I create an interface for a set of classes with almost identical functionality but with different parameters and return types?如何为一组具有几乎相同功能但具有不同参数和返回类型的类创建接口?
【发布时间】:2019-10-10 23:42:51
【问题描述】:

我有一系列几乎做同样事情的课程。以下是 2 个预期子类的样子:

class ItemWriter
{
    private List<Item> items;

    public ItemWriter(List<Item> items)
    {
        this.items= items;
    }

    public List<Item> Write()
    {
        using (var ctx = new DatabaseEntities())
        {
            using(var trx = ctx.Database.BeginTransaction())
            {
                ctx.Item.AddRange(items);
                rowsAdded = ctx.SaveChanges();
                trx.Commit();
            }
        }
        return items;
    }
}

还有一个……

class ItemShelfWriter
{
    private List<ItemShelf> itemShelfs;

    public ItemShelfWriter(List<ItemShelf> itemShelfs)
    {
        this.itemShelfs= itemShelfs;
    }

    public List<ItemShelf> Write()
    {
        using (var ctx = new DatabaseEntities())
        {
            using(var trx = ctx.Database.BeginTransaction())
            {
                ctx.TtemShelf.AddRange(itemShelfs);
                ctx.SaveChanges();
                trx.Commit();
            }
        }
        return itemShelfs;
    }
}

您可以看到这两个类做的事情几乎相同 - 只是它们写入不同的表并且Write() 方法具有不同的返回类型。

我想要一个接口/抽象类IWriter.cs,它强制每个子类有一个Write() 方法返回一个类型和一个接受List 的构造函数。如果我可以删除 Write() 中的一些重复代码,那就太好了。

但是,问题在于每个类都接受并返回不同的对象并写入不同的数据库表。有什么方法可以实现/改进吗?我有一个模糊的理解,它可能是需要使用的泛型。

【问题讨论】:

    标签: c# generics inheritance polymorphism


    【解决方案1】:

    这听起来像是 generics 的好案例:

    界面:

    public interface IWriter<T>
    {
        List<T> Write();
    }
    

    您是否可以删除重复代码取决于您的真实类实际执行的详细操作。根据您展示的代码,您可以这样做:

    class Writer<T> : IWriter<T>
    {
        private List<T> items;
    
        public Writer(List<T> items)
        {
            this.items= items;
        }
    
        public List<T> Write()
        {
            using (var ctx = new DatabaseEntities())
            {
                using(var trx = ctx.Database.BeginTransaction())
                {
                    ctx.Item.AddRange(items);
                    rowsAdded = ctx.SaveChanges(); // what is rowsAdded??
                    trx.Commit();
                }
            }
            return items;
        }
    }
    

    你没有声明rowsAdded,所以我不知道该怎么办。

    你现在可以像这样实例化这个类:

    var itemWriter = new Writer<Item>(items);
    var itemShelfWriter = new Writer<ItemShelf>(itemShelfs);
    

    【讨论】:

    • 根据上下文,rowsAdded 似乎是一个 int。 OP应该澄清:)
    • 感谢 René 的回答,并为我(非常)缓慢的反应道歉。这看起来不错,但我不确定如何处理 public List Write() 方法的实现。我可以使用泛型将不同的对象传递给 Write() 方法,但是 Write() 方法为每个类调用不同的表,我想知道我们是否可以进一步减少代码重复?在您的代码中,您每次都更新 ctx.Item 表,但 IWriter 接口的每个子项都会写入不同的表。这将有效地完全消除对继承的需求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    • 2013-03-28
    • 2019-04-15
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多