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>
.