由于抽象类,无法传递类添加方法

时间:2018-03-26 15:49:30

标签: c# .net

我有一系列的记录课程,总共7个。这些是从基类Record中抽象出来的。 我的工厂创建了正确的类,将其返回到我的main方法。 接下来我调用Creator方法来构建主类;容器。 从这个类中,我在每个记录上执行特定的DB任务。目标是打包记录 进入Container并传递给任务管理器,该任务管理器创建一个线程并处理容器中的记录。 一切都很好,直到我建立容器。 Container有7个重载方法,用于将特定类型的记录类添加到正确的列表中。 这是失败的,因为RecordFactory返回的类是Record,而不是Record_40。 如果不像我这里那样创建一个开关/盒子,有没有更有效的方法呢?

//RecordFactory
public static class RecordFactory
{
    public static Record GetRecordClass(string recordType)
    {
        Type classType = Type.GetType("myClass.Record_" + recordType);
        return (Record)Activator.CreateInstance(classType);
    }
}

// Record
namespace myNamespace
{
    public abstract class Record
    {
        public void Deserialize(string input, int row);

        // Properties
        public abstract int Row { get; private set; }
        public abstract string Name { get; private set; }
        public abstract string OrderID { get; private set; }
        public abstract string CustomerID { get; private set; }
    }
}

// Record_40
    public class Record_40 : Record
    {
        public override void Deserialize(string input, int row)
        {
                Utility.Deserialize(input, row);
        }

        // Properties
        public override int Row { get; private set; }
        public override string Name { get; private set; }
        public override string OrderID { get; private set; }
        public override string CustomerID { get; private set; }
        public string TrackingNumber { get; private set; }
        public DateTime CreateDate { get; private set; }
    }

// Container class
public sealed class Container
{
    private Container()
    {

    }

    private List<Record_30> _list_30 = new List<Record_30>();
    private List<Record_40> _list_40 = new List<Record_40>();
    private List<Record_50> _list_50 = new List<Record_50>();
    private List<Record_100> _list_100 = new List<Record_100>();
    private List<Record_200> _list_200 = new List<Record_200>();
    private List<Record_250> _list_250 = new List<Record_250>();
    private List<Record_300> _list_300 = new List<Record_300>();

    public void Add(Record_30 item) => _list_30.Add(item);
    public void Add(Record_40 item) => _list_40.Add(item);
    public void Add(Record_50 item) => _list_50.Add(item);
    public void Add(Record_100 item) => _list_100.Add(item);
    public void Add(Record_200 item) => _list_200.Add(item);
    public void Add(Record_250 item) =>  _list_250.Add(item);
    public void Add(Record_300 item) => _list_300.Add(item);

    public List<Record_30> Record30 => _list_30;
    public List<Record_40> Record40 => _list_40;
    public List<Record_50> Record50 => _list_50;
    public List<Record_100> Record100 => _list_100;
    public List<Record_200> Record200 => _list_200;
    public List<Record_250> Record250 => _list_250;
    public List<Record_300> Record300 => _list_300;

    public string OrderID { get; private set; }
    public string CustomerID { get; private set; }
}

public static class ContainerBuilder
{
    private static string _orderID;
    private static string _customerID;
    private static Container _container;

    public static void PopulateContainer(Record rec)
    {
        string _recordName = rec.GetType().Name;

        if ((rec.OrderID != _orderID) || 
            (rec.CustomerID != _customerID))
        {
            TaskManager.ProcessContainer(_container);
            _container = new Container();
        }
        switch(_recordName)
        {
            case "Record_30":
                _container.Add((Record_30)rec);
                break;
            case "Record_40":
                _container.Add((Record_40)rec);
                break;
            case "Record_50":
                _container.Add((Record_50)rec);
                break;
            case "Record_100":
                _container.Add((Record_100)rec);
                break;
            case "Record_200":
                _container.Add((Record_200)rec);
                break;
            case "Record_250":
                _container.Add((Record_250)rec);
                break;
            case "Record_300":
                _container.Add((Record_300)rec);
                break;
            default:
                break;
        }
    }
}

1 个答案:

答案 0 :(得分:2)

使用dynamic删除switch

public static void PopulateContainer(Record rec) {
    if ((rec.OrderID != _orderID) || (rec.CustomerID != _customerID)) {
        TaskManager.ProcessContainer(_container);
        _container = new Container();
    }
    _container.Add((dynamic)rec);
}

这种方法可确保调用正确的重载,但代价是在传递未知子类的对象时产生运行时故障。 switch具有相同的问题,但default案例忽略了未知类型。考虑编写一个catch-all Add(Record)方法,该方法会捕获未知子类的添加内容,并在运行时提供适当的诊断。