Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 由于抽象类,无法传递类以添加方法_C#_.net - Fatal编程技术网

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

C# 由于抽象类,无法传递类以添加方法,c#,.net,C#,.net,我有一系列的记录课程,总共7个。它们是从基类Record中抽象出来的。 我的工厂创建适当的类,并将其返回到我的主方法。 接下来我调用Creator方法来构建主类;容器。 在这个类中,我对每个记录执行特定的DB任务。目标是打包这些记录 并传递给任务管理器,该任务管理器创建线程并处理容器中的记录。 在我构建容器之前,一切都很好。 容器有7个重载方法将特定类型的记录类添加到适当的列表中。 这是失败的,因为从RecordFactory返回的类是Record,而不是Record_40。 如果没有像我这里所

我有一系列的记录课程,总共7个。它们是从基类Record中抽象出来的。 我的工厂创建适当的类,并将其返回到我的主方法。 接下来我调用Creator方法来构建主类;容器。 在这个类中,我对每个记录执行特定的DB任务。目标是打包这些记录 并传递给任务管理器,该任务管理器创建线程并处理容器中的记录。 在我构建容器之前,一切都很好。 容器有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;
        }
    }
}
//记录工厂
公共静态类记录工厂
{
公共静态记录GetRecordClass(字符串记录类型)
{
Type classType=Type.GetType(“myClass.Record\uux”+recordType);
返回(记录)Activator.CreateInstance(类类型);
}
}
//记录
名称空间myNamespace
{
公开摘要类记录
{
public void反序列化(字符串输入,int行);
//性质
公共抽象int行{get;private set;}
公共抽象字符串名称{get;private set;}
公共抽象字符串OrderID{get;private set;}
公共抽象字符串CustomerID{get;private set;}
}
}
//记录40
公开课记录(40:记录)
{
public override void反序列化(字符串输入,int行)
{
反序列化(输入,行);
}
//性质
公共重写int行{get;private set;}
公共重写字符串名称{get;private set;}
公共重写字符串OrderID{get;private set;}
公共重写字符串CustomerID{get;private set;}
公共字符串跟踪编号{get;private set;}
public DateTime CreateDate{get;private set;}
}
//集装箱类
公共密封类集装箱
{
专用容器()
{
}
私有列表_List_30=新列表();
私有列表_List_40=新列表();
私有列表_List_50=新列表();
私有列表_List_100=新列表();
私有列表_List_200=新列表();
私有列表_List_250=新列表();
私有列表_List_300=新列表();
公共作废新增(记录项)=>(列表项)新增(项);
公共作废添加(记录项)=>\u列表项添加(项);
公共作废添加(记录项)=>\u列表项添加(项);
公共作废添加(记录\u 100项)=>\u列表\u 100.添加(项);
公共作废添加(记录项)=>\u列表项添加(项);
公共作废添加(记录项)=>\u列表项添加(项);
公共作废添加(记录\u 300项)=>\u列表\u 300.添加(项);
公共列表记录30=>\u列表\u 30;
公共列表记录40=>\u列表\u 40;
公共列表记录50=>\u列表\u 50;
公共列表记录100=>\u列表\u 100;
公共列表记录200=>\u列表\u 200;
公共列表记录250=>\u列表\u 250;
公共列表记录300=>\u List\u 300;
公共字符串OrderID{get;private set;}
公共字符串CustomerID{get;private set;}
}
公共静态类容器生成器
{
私有静态字符串_orderID;
私有静态字符串\u customerID;
私有静态容器_容器;
公共静态void PopulateContainer(记录rec)
{
字符串_recordName=rec.GetType().Name;
如果((rec.OrderID!=_OrderID)|
(rec.CustomerID!=\u CustomerID))
{
TaskManager.ProcessContainer(_container);
_容器=新容器();
}
开关(_recordName)
{
案例“记录30”:
_容器。添加((记录30)rec);
打破
案例“记录40”:
_容器。添加((记录40)rec);
打破
案例“记录50”:
_容器。添加((记录_50)rec);
打破
案例“记录100”:
_容器。添加((记录_100)rec);
打破
案例“记录200”:
_容器。添加((记录200)rec);
打破
案例“记录250”:
_容器。添加((记录250)rec);
打破
案例“记录300”:
_容器。添加((记录300)rec);
打破
违约:
打破
}
}
}

使用
动态
卸下
开关

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

这种方法可以确保调用正确的重载,但在传递未知子类的对象时会产生运行时故障<代码>开关也有同样的问题,但默认情况下,
忽略未知类型。考虑编写一个catch ->代码>添加(记录)< /> >方法,该方法将捕获未知子类的添加,并在运行时提供适当的诊断。

如何调用< <代码> PopulateContainer <代码>?容器构建程序PopulateContainer(REC);它是在GetRecordClass方法之后调用的,只是为了命名一个替代方法,即“访问者模式”-但接受的答案可能更可读、更简单。您可以在容器中使用两个
字典
,例如,首先可以存储
字符串
(类型名称)和
类型
之间的映射,第二种方法可以将特定
类型的列表存储为
IList
,然后您可以使用字典索引和快速
O(1)
查找来添加项。我觉得它比使用
动态
更麻烦,但效率也更高。大致是这样的:谢谢-我来看看访客模式。谢谢-我完全忘记了(动态)-这解决了它。谢谢你提醒我“一网打尽”的方法。