I have the following code, where i am trying to create a generic collection for the objects in my DAL (just an exercise, not actually production code). My problem is that i want to use the type passed in's Read method (which is part of an interface that the classes implement).
I cannot create a new T
so i dont have an instance of the object to work with, and i cant declare it as the base type, as i need the read method specified by the child of the base object.
Is this actually possible or am i barking up 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;
}
}
-
Can you not have a default constructor on the type(s) held by the collection and add the new() directive to the where T : directive?
public class ItemDictionary<T> where T : ILoadable, DataItem, new()
and then:-
T item = new T();
Pondidum : Thats exactly what i was missing! It even worked in VB.net :) -
It's not clear to me why you can't use
new T()
(with an appropriate constraint onT
). It's also not clear to me why you're using explicit interface implementation, and why yourILoadable
interface has a method calledILoadable
, mind you.Is the problem that you can't always guarantee to have a parameterless constructor in the object type? If that's the case, you'll certainly need something to create instances of
T
. Perhaps you actually need to separateT
from its factory, perhaps with another 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 an
IFactory<T>
implementation into yourItemDictionary<T>
constructor.Pondidum : Sorry, converted this form vb.net with an online code converter...
0 comments:
Post a Comment