简体   繁体   中英

How can I create an interface for a set of classes with almost identical functionality but with different parameters and return types?

I have a series of classes that do almost the same thing. Here's what 2 of the prospective child classes look like:

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

And another...

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

You can see that both classes do almost the same thing - only they write to different tables and the Write() methods have different return types.

I'd like to have an interface / abstract class IWriter.cs that forces every child class to have a Write() method returning a type and a constructor accepting a List. If I could remove some of the code duplication in Write() that would be good.

However, the issue is that each class takes and returns different objects and writes to a different database table. Is there any way I can achieve / improve this? I have a vague understanding that it's probably generics that need to be used.

That sounds like a good case for generics :

Interface:

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

If you can remove code duplicates depends on what your real classes actually do in detail. From the code you've shown you could do this:

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

You did not declare rowsAdded , so I don't know what to do with this.

You can now instantiate this class like:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM