views:

336

answers:

6

Hi,

I have a public static property in a class. The class has some custom attributes applied to it. I want to access the Attribute in a static property.

In a non-static member I can get the type of current class using this.GetType() but how do I do this in a static member of the class ?

Please note that..

  • I do not want to use typeof(typename) due to inheritance issues. [I will have this property inherited to derived classes.].

  • I also do not want to use Generics as well.

EDIT

Here's my objective.

I have an abstract base class called EntityBase. All my entities derive from this class. Each entity also carries a custom attribute called TableMappingAttribute that lets me know the table it refers/maps to, during runtime. I already have a property in EntityBase that returns me the mapped TableName for the entity.

I will always need an instance of entity to access the TableName property. I wish to access this property statically sometime, like MyEntity.TableName. I have large amount entities in my project. I want this static property to be added in EntityBase class itself. So I must discover the type at runtime. How do I do this in EntityBase class itself ??

Thnaks.

+3  A: 

You can't, basically. typeof(...) is what you need to use.

Bear in mind that if you try to use:

Type type = MyDerivedType.SomeStaticProperty;

which is declared in MyBaseType, that will actually end up being compiled to

Type type = MyBaseType.SomeStaticProperty;

anyway. Static members basically aren't polymorphic. If you try to use them polymorphically, you'll run into problems like this.

EDIT: So from your edit, it looks like you're trying to do exactly the above type of thing, with

MyEntity.TableName

instead of

EntityBase.TableName

It just won't work. The compiler will emit code to fetch EntityBase.TableName. The runtime has no concept of "the current class". There's no context here.

Basically you need to change your design. If you want to use inheritance, you may want to have a parallel hierarchy - one for the metadata (things like table names) and one for the actual objects. So you'd have something like:

public class MyEntity : EntityBase<MyEntityType>

where MyEntityType derives from EntityType in the parallel hierarchy. Then you can use inheritance within the metadata hierarchy.

Alternatively, just making EntityBase generic anyway will let you get at the type of entity you're talking about:

public class MyEntity : EntityBase<MyEntity>

I know you said you didn't want to use generics, but as what you want to do just won't work, you should at least consider it...

Jon Skeet
Thanks jon. I did it the same way at first using Generics. And was trying to find out a non-generic alternate. But I nw knw its not possible. Thnks again.
this. __curious_geek
A: 

You can use the System.Diagnostics.StackFrame class in a static method like this:

StackFrame currentStackFrame = new StackFrame();
Type type = currentStackFrame.GetMethod().DeclaringType;
Martin Liversage
That will have the same problem the OP has with typeof - it'll give the base type rather than the derived type.
Jon Skeet
I'm answering the question "In a non-static member I can get the type of current class using this.GetType() but how do I do this in a static member of the class [without using typeof()] ?". The inheritance stuff doesn't make sense to me. But I guess typeof() is much easier to use and understand.
Martin Liversage
+2  A: 

I do not want to use typeof(typename) due to inheritance issues.

static properties aren't inherited in the normal sense. Sure, they are in-scope, but that isn't the same. The only way to get what you want would be to look at the stack-frame, but that is ugly and hacky (and risky if optimisations are enabled).

I'd refactor for a solution that uses the instace... instance have a Type.

Marc Gravell
A: 

You don't need to worry about inheritance if the property is static; it cannot be overridden, so it will always be declared in the base class anyway. Using typeof is the way to go.

Fredrik Mörk
A: 

If you don't want to use typeof(), then you're out of luck, because that's the only way to get the Type object of a static class (unless you want to find the type by calling Type.GetType() and look for it by name)

I don't see the problem with inheritance though.

Type type = typeof(YourStaticClass);

Attribute[] attributes = type.GetCustomAttributes(...);
Philippe Leybaert
A: 

A parent don't know how many childs it has. But a child know about its parent. The only way a parent should know about the child is through polymorphism which is not an attribute of static members.

What you are trying to do is to know about the child class in a public static property of parent. Why don't you consider sending your child class reference as a parameter in the static method in your base class and then in the base class have the reference of the child class by calling its GetType method...

public static string GetTableName(BaseClass childsObjectWrappedInBaseReference) {
   Type type = childsObjectWrappedInBaseReference.GetType();
   ....
   ....
}
S M Kamran
read the edit..
this. __curious_geek
Instead of static property use static method and pass in the reference of your child class.
S M Kamran
This way you don't have to implement this in all the child classes and you can access it in static manner.
S M Kamran
The point here is that you can't access a child class from it's parent without a reference. Either parent get the reference polymorphically or you explicitly pass the reference to parent.By the way In your code from where you are calling EntityBase.TableName property you should have a reference of the child class and if you don't then you should some how be aware of the child entity name or some thing which you'll be updating... If you know the name then you can pass in the name to method and instantiate the child class object with the help of say some naming convention or signature pattern.
S M Kamran
I do not wish to create any object. If I wanted to I'd never go for static prop.
this. __curious_geek