C# Is it possible to get the type of a class in its static method?

Started by
16 comments, last by Timberl 18 years, 7 months ago
Quote:Original post by antareus
No inheritance is taking place with static methods. The base class's implementation may be obscured by a subclass implementation, but that isn't the same thing as inheritance. If you're interested in knowing the type of the derived class, add a Type argument to the static method's argument list. Classes (be they base or derived) can simply pass in this.GetType() (or obj.GetType()) for that argument.


I have a class. it has a static method. I subclass my class. my subclass has the static method. how is that not inheritance?

Quote:
As Arild Fines said, it makes absolutely no sense.

A static method is has only one "instance" in memory; every time you call it, it's that same code that is called. It receives no this pointer. How can you expect it to return different results depending on who calls it?

Tell us what you intend to do with it and we might provide you with a better solution.


A concrete example:

Okay. I have a class called 'View'. it gives me lots of functionality for searching on my objects and my UI knows how to display (and therefore subclasses of it). (in an ideal world this class would be abstract, however in order to use Designer in VS it can't be abstract - using VS & its Designer is out of my control)

I also have a car class and a driver class.

I then make 2 subclasses of View, one called 'carView' and another called 'driverView'.

now I know there is a link between carView and car and between driverView and driver. I would have naturally wanted to express this with a static method or property on the View , something like: public static Type targetObjectType. logically, the target-object-type is defined at the class-level. its shared across all objects of the same class.

When my window manager (or whatever) gets hold of my carView, all it sees it as is a View. I do not want it to specifically know about any one of my subClassed view-s.

I also don't want car - my data object - to know about carView.

I'm now given a car object, I want to be able to find a view to represent it. I would do this by reflecting on my assembly, trotting over the different Types in my assembly at run-time and making an index relating an object-type to a view type so I could look it up. I don't want to instantiate every search screen in my assembly to build this index.

does this make it more clear?
Advertisement
Have a pure-virtual method GetTargetObjectType whose implementations each return the appropriate type. However, depending on what exactly you want the type for, you may want to consider an Abstract Factory pattern or a Bridge pattern.
Quote:Original post by Timberl
Quote:Original post by antareus
No inheritance is taking place with static methods. The base class's implementation may be obscured by a subclass implementation, but that isn't the same thing as inheritance. If you're interested in knowing the type of the derived class, add a Type argument to the static method's argument list. Classes (be they base or derived) can simply pass in this.GetType() (or obj.GetType()) for that argument.


I have a class. it has a static method. I subclass my class. my subclass has the static method. how is that not inheritance?

Static methods belong to the base class, not the derived class.

Quote:I'm now given a car object, I want to be able to find a view to represent it. I would do this by reflecting on my assembly, trotting over the different Types in my assembly at run-time and making an index relating an object-type to a view type so I could look it up. I don't want to instantiate every search screen in my assembly to build this index.

does this make it more clear?

I'm not sure I see the advantage of doing it this way. You're still linking a particular View implementation (CarView, in this case) to the Car type.

Wouldn't it make more sense to pass this in as a parameter to the Car constructor by making IView an interface? That answers the question "Which IView is this Car instance using?" without revealing the specifics of the IView to the Car object. The appropriate methods are called and the appropriate behavior is invoked, but Car has no knowledge of whether it's using a CarView or LlamaView or a MotorcycleView. Is that what you want?
- k2"Choose a job you love, and you'll never have to work a day in your life." — Confucius"Logic will get you from A to B. Imagination will get you everywhere." — Albert Einstein"Money is the most egalitarian force in society. It confers power on whoever holds it." — Roger Starr{General Programming Forum FAQ} | {Blog/Journal} | {[email=kkaitan at gmail dot com]e-mail me[/email]} | {excellent webhosting}
Quote:Original post by Sneftel
Have a pure-virtual method GetTargetObjectType whose implementations each return the appropriate type. However, depending on what exactly you want the type for, you may want to consider an Abstract Factory pattern or a Bridge pattern.


Like I said, I don't have the possibility of making the method abstract. And even if I did, I couldn't make it static. Which is what I'm trying to achieve

Quote:Original post by kSquared
I'm not sure I see the advantage of doing it this way. You're still linking a particular View implementation (CarView, in this case) to the Car type.

Wouldn't it make more sense to pass this in as a parameter to the Car constructor by making IView an interface? That answers the question "Which IView is this Car instance using?" without revealing the specifics of the IView to the Car object. The appropriate methods are called and the appropriate behavior is invoked, but Car has no knowledge of whether it's using a CarView or LlamaView or a MotorcycleView. Is that what you want?


Yes, but carView is created especially for car, I dont mind it knowing a car object - theres nothing wrong with that logically. I do mind the car which is a data object carrying 'view' info in its state. What if there's more than one view? if I send this car object over the network, I dont want the 'view' associated to it being passed along with it. And I especially dont want to declare which 'View' to use for a particular car object because I think my system should be smart enough to work that out.

see my solution below if interested

[Edited by - Timberl on September 7, 2005 4:46:20 AM]
FYI, my solution, which I dont completely like, is to allow an attribute TargetObject to be put on a class. (attributes are one of c#'s few good ideas that haven't just been pulled off java)

e.g.

[TargetObject( typeof( Car ) )]class CarView{  ...}


then I have a static method in my window-manager class definiton:

class WindowManager{    public static Type getObjectType( Type t ){        // get the targetObjectType from the attribute on type t    }}

et voila.

no instantiation of any view-class needed.

When I want to know what object a view acts on I just do

WindowManager.getObjectType( typeof(carView) );

so basically I'm storing the info as meta-data in the View (although note, attributes can actually have validation code - type checking etc. - they are actual objects, not just 'text')

unorutnately I cant make this attribute required at compile-time. but other than that I pretty much get what I wanted
Why is it important to the attribute is present at compile-time? Anyway, as I said in your other thread, you can always make a small helper app which checks for the presence of these attributes and make it a post-build step.
If it's a matter of safety (loading custom classes dynamically and not wanting to have to deal with exceptions in the middle of your game) you can just check the attributes when you load these classes.

WindowManager.getObjectType( typeof(carView) );

This is a bad example, since it implies you have all information necessary at compile-time, and you're deferring the Car-selection to runtime. You might just as well write "typeof(Car)", it's more efficient.

You need to tell us based on what information you need to make the type-selection. Do you receive a Type-object (of a View)? (In this case, attributes are the way to go) Or an instance of such a View? (Polymorphism) Or something that represents the type of a view (a custom Type-class in a way)? In this case you can fake "virtual class methods" by implementing classes as objects (CarViewClass, a bit like the factory design pattern, or also comparable to Java 1.5's enums).
Quote:Original post by SamLowry
Why is it important to the attribute is present at compile-time?


safety. avoiding blowing up at runtime.
Quote:

WindowManager.getObjectType( typeof(carView) );

This is a bad example, since it implies you have all information necessary at compile-time, and you're deferring the Car-selection to runtime. You might just as well write "typeof(Car)", it's more efficient.


Yes, okay, carViews a bad example. As I keep trying to stress, in reality I might just have the Type - and all I know is that it is a subclass of View.

Quote:
You need to tell us based on what information you need to make the type-selection. Do you receive a Type-object (of a View)?


Yes.

like I said, I reflect over the classes in my assembly to make the associtations at run-time.

Quote:
(In this case, attributes are the way to go) Or an instance of such a View? (Polymorphism) Or something that represents the type of a view (a custom Type-class in a way)? In this case you can fake "virtual class methods" by implementing classes as objects (CarViewClass, a bit like the factory design pattern, or also comparable to Java 1.5's enums).



and I dont like the idea of a post-build or pre-build step, unless it could be integrated into VS.
And anyway, all this comes down to is there are times when you want to put static information in a class, and it is such a common feature you would like it to be described in a parent. It doesn't matter that you could figure out the info -- even if I do know that 'car' is my 'carView' class' object-type, the very fact that I am hard-coding my knowledge into the program is a flaw as far as I'm concerned and means I change code everywhere I used this knowledge if I change the backing object to carView.

This topic is closed to new replies.

Advertisement