Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

Calling type of a derived static method

I've got a static method (GetMyType) in a class (let's call it ParentClass) and another class (ChildClass) which inherits ParentClass. By calling the 'GetMyType' method from ChildClass I want to be able to find out the type of the child class without having to modify the method in any way.

so here's the code I've got at the moment:

public class ParentClass {
  public static string GetMyType() {
    return MethodBase.GetCurrentMethod().DeclaringType.Name;
  }
}

public class ChildClass : ParentClass {

}

when I call ChildClass.GetMyType() it returns 'ParentClass'.

I want it to return 'ChildClass'. Does anyone have any ideas as to how to achieve this without redeclaring the GetMyType method in the child class.

It might look really petty what I'm trying to achieve, but this method will be called from many many derived classes and would save a lot of time and code.

cheers

Marcus

Marcus Greenwood
Tuesday, October 14, 2003

Have you looked at the built-in typeof() operator? It returns a System.Type object, and I'm pretty sure Type should have some property or method that returns the type's name (probably simply ToString).  If so, you only need a single line in your method:

return typeof(this).ToString();

And typeof should correctly deal with derived types, too (ie return the Type of the derived class where applicable).

Chris Nahr
Tuesday, October 14, 2003

Erm, I just noticed that your method is static so you can't use this... but never mind, I'm stupid anyway since typeof takes type names, not objects!

So never mind my reply, it seems you do have to use some kind of explicit reflection. I'll have to think about it.

Chris Nahr
Tuesday, October 14, 2003

The short answer is: you aren't going to get what you want, because the method is static. There are some languages that support the (IMO, odd) concept of 'virtual static', but C# isn't one of them.

Brad Wilson (dotnetguy.techieswithcats.com)
Tuesday, October 14, 2003

Thought as much. Though I thought I was quite close with the MethodInfo stuff, but after trying a few different variations I could only get it to return the name of the parent class.

cheers

Marcus

Marcus Greenwood
Tuesday, October 14, 2003

myVar.GetType()?

Thomas Eyde
Thursday, October 16, 2003

No, the problem is that he wants to use static methods so he doesn't have an instance to use GetType on.

Chris Nahr
Thursday, October 16, 2003

I am curious. What do you need this for? Why can't you ask an instance?

Thomas Eyde
Thursday, October 16, 2003

myVar.GetType() is the way to go.  I believe you need to re-think why you want this to be in a static function.  Show us the situation where you need the type of an object without having an instance of it please if I'm wrong.

Chris M
Thursday, October 16, 2003

ok, this is quite complex, but here goes:


I have a class which represents all objects which might be loaded from the database. It is called DBClass

DBClass has many classes which inherit it. For example the class Country is a class which represents the 'country' table in my database.

DBClass has a method called GetAll. This executes a simple stored procedure and returns an ArrayList of all items of a particular derived type from the database. However, because the GetAll method is declared in the DBClass and not in Country, it doesn't know which type of class all of the objects in the arraylist should be and therefore doesn't know which fields they all contain (the field definitions are stored in the classes themselves). Therefore, because I don't know what the field definitions are for the Country class when I run Country.GetAll() I needed to modify the GetAll method so that it would take a parameter which represented an instance of the Country class which I'm trying to make lots of copies of. So therefore the current signature of GetAll is:

public static ArrayList GetAll(object dbClassPrototype)

and when I run GetAll from the Country class I need to call it like so:

ArrayList countryArrayList = Country.GetAll(new Country());

new Country() is the prototype object which I will copy lots of times when I insert all of the countries returned into the arraylist. GetAll also converts the type of objects in the arraylist so that they are of the Country type. Therefore I am able to do the following:

foreach(Country countryObject in countryArrayList) {
  ... do stuff
}

What I want to achieve is like so:

ArrayList countryArrayList = Country.GetAll();

foreach(Country countryObject in countryArrayList) {
  ... do stuff
}

but... without having to redeclare the GetAll method in the Country class. So, therefore in order to be able to do this, the GetAll method must be able to work out from which class it's being called. Then I will be able to create an instance of the dbClassPrototype object (through reflection) and not have to pass it into the GetAll method.

This is what I meant by really petty. I will save roughly 3 lines of code per class which inherits DBClass, but I'm trying to create a framework which my company can re-use by writing as little code as possible.

Marcus

Marcus Greenwood
Friday, October 17, 2003

Assuming GetAll() in the end calls a proc without parameters which then executes a select [fields] from [table]:

DBClass:

public static ArrayList GetAll() {
    string spName = GetSpName();
    ArrayList list = new ArrayList();

    foreach(DataRow r in StoredProcedure.GetRows(spName))
        list.Add(CreateInstanse(r));

    return list;
}

protected static abstract string GetSpName();
protected static abstract object CreateInstance(DataRow r);

Not shure if above abstracts works with statics, but I assume it does: Then all derived classes are forced to implement those methods, in which you provide the specialized code.

In Country:

protected override string GetSpName() {
    return "spGetAllCountries";
}

protected override Country(DataRow r) {
    Country c;
    // create and fill c with data from r
    return c;
}

No need for GetType at all.

Thomas Eyde
Friday, October 17, 2003

That should be

    protected override Country CreateInstance(DataRow r)

Thomas Eyde
Friday, October 17, 2003

Dude, if you want to OVERRIDE the parent static method you have to override it.  In otherwords you gotta write the method.

The question you ask points to a likely misunderstanding about objects, methods and the static keyword.  And about C# and the object class.  It sounds like the questions of a C++ programmer who's a bit lost in C#.

Go learn some C#.

1.  The C# object class has a (non-static, of course! as it should be) .GetType() method.  The Type class has a static (as it should be) GetType(string typeName) method.  Then there's the C# typeof keyword/operator.

2.  static methods don't do polymorphism.  BUT they do bind to the name of the invoked type.  In otherwords, you've named the type you're invoking on buit there's no defined method so it invokes the inherited method as it should.  get a book on the language.  It seems clear that what you want to do is trivial and the way you are doing it is confused.

joe
Tuesday, October 21, 2003

Okay, okay, I was just trying to save writing a couple of lines of code. No great loss. I accept it isn't possible, but the reason I asked is because I wasn't sure and it's not the kind of thing which is covered in a book. Nevermind.

Marcus Greenwood
Wednesday, October 22, 2003

*  Recent Topics

*  Fog Creek Home