views:

1267

answers:

7

I recently ran into a problem where it seems I need a 'static abstract' method. I know why it is impossible, but how to work around?

For example I have an abstract class which have a description string. Since this string is common for all instances it is marked as static, but I want to require that all classes derived from this class provide its own Description property so I marked it as abstract:

abstract class AbstractBase
{
    ...
    public static abstract string Description{get;}
    ...
}

It won't compile of course. I thought of using interfaces but interfaces may not contain static method signatures.

Should I make it simply non-static, and always get an instance to get that class specific information?

Any ideas?

+8  A: 

You cant.

The place to do this is with Attributes.

Eg

[Name("FooClass")]
class Foo
{
}
leppie
Clever. . .
Shog9
Indeed... one could have the public static Description property pick up the attribute value though to make it more accessible...
Peter Lillevold
Would be interested to know how that works out at runtime. Does the attribute end up as an instance var somehow? I've read custom attributes before through reflection, but dont know how the CLR handles them
Chad Grant
You can do a GetType on an object and get the list of custom attributes decorating that type via reflection. Each Custom Attribute can have its own state that it can expose via properties.
Gishu
Wouldn't reflecting like that be expensive?
bdonlan
+2  A: 

It's not static if it has to be called on an instance.

If you're not calling it on an instance, then there's no polymorphism at play (i.e. ChildA.Description is completely unrelated to ChildB.Description as far as the language is concerned).

Yuliy
+2  A: 

Combining static and abstract is somewhat meaningless, yes. The idea behind static is one need not present an instance of the class in order to use the member in question; however with abstract, one expects an instance to be of a derived class that provides a concrete implementation.

I can see why you'd want this sort of combination, but the fact is the only effect would be to deny the implementation use of 'this' or any non-static members. That is, the parent class would dictate a restriction in the implementation of the derived class, even though there's no underlying difference between calling an abstract or 'static abstract' member (as both would need a concrete instance to figure out what implementation to use)

bdonlan
I thought the situation again, and I'm say that's true...public abstract string {get;} impletented like public string {get {return "Izeeeeeeeeh";}} is enough class specific.
Calmarius
+1  A: 

If it is static, there is only one instance of the variable, I don't see how inheritance would make sense if we could do what you want to accomplish with static vars in derived classes. Personally I think you are going to far to try to avoid a instance var.

Why not just the classic way?

abstract class AbstractBase
{
    protected string _Description = "I am boring abstract default value";
}

class Foo : AbstractBase {

     public Foo() {
       _Description = "I am foo!";
     }
}
Chad Grant
A: 

`abstract class AbstractBase { string description = string.Emtpy;

AbstractBase() {}

public AbstractBase(string description) { this.description = description; }

protected string Description { get { return this.description; }

}

class YourClass : AbstractBase { public YourClass() : base("ItNeedsToProvideIt") { }

public void Something()
{
 //You can use this.Description
}

}`

Khurram Aziz
A: 

If you don't mind deferring to implementations to sensibly implement the Description property, you can simply do

public abstract string ClassDescription {get; } 
// ClassDescription is more intention-revealing than Description

And implementing classes would do something like this:

static string classDescription="My Description for this class";
override string  ClassDescription { get { return classDescription; } }

Then, your classes are required to follow the contract of having a description, but you leave it to them to do it sensibly. There's no way of specifying an implementation in an object-oriented fashion (except through cruel, fragile hacks).

However, in my mind this Description is class metadata, so I would prefer to use the attribute mechanism as others have described. If you are particularly worried about multiple uses of reflection, create an object which reflects over the attribute that you're concerned with, and store a dictionary between the Type and the Description. That will minimize the reflection (other than run time type inspection, which isn't all that bad). The dictionary can be stored as a member of whatever class that typically needs this information, or, if clients across the domain require it, via a singleton or context object.

JasonTrue