General loading of a collection from a generic type
I have the following code where I am trying to create a generic collection for objects in my DAL (just an exercise, not production code). My problem is that I want to use the type passed in the Read method (which is part of the interface implemented by the classes).
I can't create new T
, so I don't have an instance of the object to work with, and I can't declare it as a base type, since I need a read method specified by a child of the base object.
Is this possible or am I barking on the wrong tree?
public class ItemDictionary<T> where T : ILoadable, DataItem
{
public void Load()
{
using (IDataReader reader = SqlHelper.ExecuteReader(_connection, CommandType.StoredProcedure, _proc)) {
Read(reader);
}
}
bool Read(IDataReader reader)
{
while (reader.Read)
{
T item = default(T); //Here be the problem
if (item.Read(reader))
{
this.Add(item.Guid, item);
}
}
return true;
}
}
public class ExampleObject : DataItem, ILoadable
{
bool Read(IDataReader reader)
{
_var1 = reader.getString(0);
_var2 = reader.getString(1);
_var3 = reader.getString(2);
return true;
}
}
a source to share
It's not clear to me why you can't use new T()
(with a corresponding restriction on T
). It is also not clear to me why you are using an explicit interface implementation, and why your ILoadable
interface has a method called ILoadable
, mind you.
Is the problem that you can't always guarantee that there is a parameterless constructor in the object type? In this case, you will certainly need to create instances T
. Perhaps you really need to decouple T
from its factory, perhaps with a different interface:
public interface IFactory<T>
{
// Roughly matching your current API
bool TryRead(IDataReader reader, out T);
// Simpler if you can just throw an exception on error
T Read(IDataReader reader);
}
Then you can just pass the implementation IFactory<T>
to your constructor ItemDictionary<T>
.
a source to share