Reputation: 297
I have a series of record classes, 7 in total. These are abstracted from a base class, Record. My factory creates the proper class, returning it to my main method. Next I call Creator method which builds the master class; Container. From this class, I perform specific DB tasks on each of the records. The goal is to package the Records into the Container and pass to a Task Manager that creates a thread and works on the records in the container. Everything works great, until I build the container. The Container has 7 overloaded methods to add the record class, of a specific type, into the proper list. This is failing, as the returned class from the RecordFactory is Record, rather than Record_40. Without creating a switch/case as I have here, is there a more efficient way to do this?
//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;
}
}
}
Upvotes: 2
Views: 57
Reputation: 726809
Use dynamic
to remove the switch
:
public static void PopulateContainer(Record rec) {
if ((rec.OrderID != _orderID) || (rec.CustomerID != _customerID)) {
TaskManager.ProcessContainer(_container);
_container = new Container();
}
_container.Add((dynamic)rec);
}
This approach ensures that the proper overload is called, at the expense of producing a run-time failure when an object of an unknown subclass is passed. switch
has the same problem, but the unknown type is ignored by the default
case. Consider writing a catch-all Add(Record)
method that would trap additions of unknown subclasses, and provide appropriate diagnostics at run-time.
Upvotes: 2