Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# abstract class return derived type enumerator

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?

like image 999
Connell Avatar asked Feb 25 '23 02:02

Connell


2 Answers

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?

like image 120
Flynn1179 Avatar answered Feb 26 '23 17:02

Flynn1179


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.

like image 26
Cheeso Avatar answered Feb 26 '23 16:02

Cheeso