If I have an abstract class, is there any way I can return an enumerator of the derived class's type? Or would I have to use generics in the base class, or a generic method? Here's a really dumbed down example of what I'm trying to do -
public abstract class Person {
public IEnumerable<MyType> Search() {
DbDataReader reader = Database.Instance.ExecuteReader(sql);
while(reader.Read()) {
MyType row = new MyType();
row.Load(reader);
yeild return row;
}
}
private Load(DbDataReader reader) {
//load instance from reader row
}
//declare properties that can be searched, such as Location
}
public class Programmer : Person {
//declare properties that can be searched, such as Language
}
Then somewhere else I'd like to be able to call
Programmer programmer = new Programmer();
programmer.Location = "My city";
programmer.Language = "C#";
foreach(Programmer programmer in programmer.Search())
{
//display list of c# programmers in my city
}
I know I can do this with a generic method, like Search<T>()
, but I'd like to be able to call the search function from a class that does not know exactly type the Person is (for example, a base class for an AJAX handler)
If this cannot be done, can anyone give me an example or reason why not? Or would it just be too hard to implement into the compiler?
There's no reason you can't make your Search method generic:
public IEnumerable<T> Search<T>() where T : MyType, new() {
DbDataReader reader = Database.Instance.ExecuteReader(sql);
while(reader.Read()) {
T row = new T();
row.Load(reader);
yield return row;
}
}
and call programmer.Search<Programmer>()
.
Where does MyType
come from btw? Should that be Person
?
See http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx
Covariance on virtual method return types is a fairly frequently requested feature, and I'd use it if I had it. It's never made the bar because (1) the CLR does not support it; we'd have to either generate lots of helper code behind the scenes to make it work, or convince the CLR team to change (the C++/CLI team did the former) (2) in most cases you can generate the necessary helper functions yourself quite easily; just make a "new" method that has the right return type that delegates its implementation to the virtual method, and (3) Anders does not consider it to be a particularly important feature. - Eric
So, No, it isn't possible, and YES, it's because it's too hard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With