I have a class that contains a lot of functionality called Record. In the system there exist two basic types of records that have a primary key that is uint, and those that have a primary key of Guid.
The Record class contains all the features that I need except for one property. Record.ID allows the developer to read the current primary key as the correct type (uint or Guid).
To achieve this I had to create three classes like this (simplified example):
class Record {
... lots of code ...
}
class RecordInt : Record {
public uint ID { get; set; }
}
class RecordGuid : Record {
public Guid ID { get; set; }
}
This works ok, but it introduced a problem where data models can't just create a generic Record instance. They have to know if derive classes are expecting RecordInt or RecordGuid. So I added a template argument to models like this.
class abstract class Model<T> : were T : Record, new()
{
... lots of generic code that uses T ...
// example
public List<T> Find(...) {
.. find a record ...
return new List<T>();
}
}
This has caused me more problems than the benefit of simply having two Record types. Now when I instantiate a model the code has to know what type of Record is required. If that takes place in a section that should be generic, then I have to add another template argument.
I found after a while there started to be a lot of methods using template arguments. Just so that type could be passed to Model<RecordGuid>, and sometimes I have to pass the template argument down a chain of several method calls befor it gets to code that really needs it.
Is there a more effective pattern then what I'm doing?
EDIT:
One reason why Model is using a template argument is that it needs to have methods that return collections of Record. In C# you can't cast List<Record> to List<RecordGuid> so I had to use a template argument for the return type as List<T>.