Static Abstract methods? Why not?

  • Thread starter Thread starter Mike Ruane-Torr
  • Start date Start date
M

Mike Ruane-Torr

Why can't I have a static abstract method in C#?

My intention is to have a class-level method that returns a string to
supply information about inherited classes, and it is natural to make this
static so that I don't need an instance in order to call it. However,
because my class model is using a common base class, I need to make it
abstract too, so that inherited classes are forced to implement it.

Am I doing something that can be done another way, or considered 'ugly' in
OOD? Or is C# being inconsiderate?
 
Mike said:
Why can't I have a static abstract method in C#?

Static members cannot be virtual. That makes sense when you think about it.
I've never heard of the concept of static polymorphism.

<I'm learning new stuff all the time>

--
There are 10 kinds of people. Those who understand binary and those who
don't.

http://code.acadx.com
(Pull the pin to reply)
 
Mike Ruane-Torr said:
Why can't I have a static abstract method in C#?

My intention is to have a class-level method that returns a string to
supply information about inherited classes, and it is natural to make this
static so that I don't need an instance in order to call it. However,
because my class model is using a common base class, I need to make it
abstract too, so that inherited classes are forced to implement it.

You might like to think about how you would call the method, if you
could implement it... if you don't have an instance, how would the
compiler or runtime know which implementation to call?
Am I doing something that can be done another way, or considered 'ugly' in
OOD? Or is C# being inconsiderate?

See my response to the post from phoenix entitled "interface and static
(abstract base class?)" from a few days ago for more information.
 
Frank Oquendo said:
Static members cannot be virtual. That makes sense when you think about it.
I've never heard of the concept of static polymorphism.

<I'm learning new stuff all the time>

I *think* Smalltalk effectively has it - but I wouldn't like to say for
sure, not knowing ST myself.
 
Why can't I have a static abstract method in C#?

abstract methods are implicitly virtual, virtual methods require an
instance.

You can have a static method in an abstract class, it just cannot be static
abstract (or abstract static).
My intention is to have a class-level method that returns a string to
supply information about inherited classes, and it is natural to make this
static so that I don't need an instance in order to call it. However,
because my class model is using a common base class, I need to make it
abstract too, so that inherited classes are forced to implement it.

Do you have an example of what you're trying to do? If a static abstract
method were available what you're suggesting would be impossible anyway.
Perhaps there is another way of doing what you want.

If you're expecting derived classes to implement it, you need an instance
because without an instance it wouldn't know which one you wanted to call.

n!
 
You might like to think about how you would call the method, if you
could implement it... if you don't have an instance, how would the
compiler or runtime know which implementation to call?


See my response to the post from phoenix entitled "interface and static
(abstract base class?)" from a few days ago for more information.
OK, I just read it. So basically, I can't do it because it isn't allowed,
but you accept that it would be nice to have the feature, if I read your
response correctly.

It is a little irksome, because now I will have to make non-static,
non-virtual methods and override them with 'new' in the derived classes -
however, I will also need to implement the methods in the base class,
which doesn't make sense in the context of my design model. Perhaps I
shall just make them return a string that says ".Net needs a new feature!"
:)
 
Mike,
For arguments sake lets look at it practically on how you'd see
it being used

abstract class A {
public static abstract string functionA();
}

class B : A {
public static string functionA() {
return "B";
}
}

Now if your're going to be calling it...
would'nt you be calling it

B.functionA();

at which point wouldnt you already be knowing what type it is? because
you're calling the function explicitly *B.*. Let me know if I din't
understand your requirement, hope that helps
 
Mike Ruane-Torr said:
OK, I just read it. So basically, I can't do it because it isn't allowed,
but you accept that it would be nice to have the feature, if I read your
response correctly.

Sort of. It's not just a case of the compiler disallowing it just to be
annoying - it's because if the compiler *did* allow it without further
language changes, it would be pretty useless. (I suspect it would also
require CLR changes, although I'm not sure.)
It is a little irksome, because now I will have to make non-static,
non-virtual methods and override them with 'new' in the derived classes -
however, I will also need to implement the methods in the base class,
which doesn't make sense in the context of my design model. Perhaps I
shall just make them return a string that says ".Net needs a new feature!"
:)

Instead of that, you could implement it with by convention, and then
invoke the method by reflection. You'd also want to write a tool to
make sure that all the appropriate types *did* actually implement the
method, probably.
 
Mike,

To call a static method, you need to scope it by the class name e.g.
SomeClass.SomeMethod. So, effectively, to call a static method you already
know what class your calling it on. The fact that you know what class your
calling means that by definition you don't need polymorphism i.e. you don't
need abstract or virtual.

Am I missing something?

-Jason
 
Mailing Lists said:
To call a static method, you need to scope it by the class name e.g.
SomeClass.SomeMethod. So, effectively, to call a static method you already
know what class your calling it on. The fact that you know what class your
calling means that by definition you don't need polymorphism i.e. you don't
need abstract or virtual.

Am I missing something?

Yes - the extra bit of functionality I was talking about. You often
have the concrete type as a Type object, but not otherwise.
Alternatively, you may have an instance of the concrete type, but not
know in advance what it is. There could be syntax such that you could
call, say:

ISomeInterface<typeOfPlugin>.SomeMethod();

or

ISomeInterface<instance>.SomeMethod();

(syntax made up on the spot).

The main place (IME) where this would be useful would be for
constructors. If everything which implemented the interface had to
provide a certain constructor, you could do something like:

ISomeInterface instance = new ISomeInterface<typeOfPlugin>(parameters);

That would be much more type-safe (if appropriately implemented in the
compiler and specs) than the current way of doing things, which is by
reflection with no real safety.
 
Jon,
I din't quite understand your comments.
Yes - the extra bit of functionality I was talking about. You often
have the concrete type as a Type object, but not otherwise.

Every class abstract or otherwise has a type and you could get it by
using the typeof operator. Is this what you meant?
Alternatively, you may have an instance of the concrete type, but not
know in advance what it is. There could be syntax such that you could
call, say:
Why wouldnt you know what type it is? from the type object you could get
all this information
 
The first case assumes you have a System.Type object, which means you can
instantiate the type it describes--and call methods on it--if you desire.
The second case starts with you holding an instance which can be cast to the
interface you're interested in using. I still don't get it....

Question: Assume a class 'A' with a static abstract method m(). Now, you've
also got two other classes, 'B' and 'C' which inherit from 'A' and override
and implement m() as required. When my code calls A.m(), which of these two
(B.m() or C.m()) should execute? Isn't this what the original post was
aiming for with the "no this pointer" requirement? Again, I could be
missing something, but this seems ambiguous/unresolvable to me.
 
Dilip Krishnan said:
Every class abstract or otherwise has a type and you could get it by
using the typeof operator. Is this what you meant?

You may not know the type name in advance though - the type may not
even have been written when you write the code! (Think of a plugin
situation.)
Why wouldnt you know what type it is? from the type object you could get
all this information

You could certainly call GetType() on the object, yes. I'd have to see
lots of use cases before deciding whether or not it was worth having it
as extra syntax, or whether it should only work on the type itself.
 
Mailing Lists said:
The first case assumes you have a System.Type object, which means you can
instantiate the type it describes--and call methods on it--if you desire.

How, exactly, without using reflection which diminishes type safety?
Without any extra facilities, you can't guarantee that a type has a
constructor with specific parameters.

Plugins are typical here - you can't guarantee what constructors will
be there, nor can you specify (in a compiler-checkable way) what
constructors the calling code will expect.
The second case starts with you holding an instance which can be cast to the
interface you're interested in using. I still don't get it....

Question: Assume a class 'A' with a static abstract method m().
Yup.

Now, you've
also got two other classes, 'B' and 'C' which inherit from 'A' and override
and implement m() as required. When my code calls A.m(), which of these two
(B.m() or C.m()) should execute? Isn't this what the original post was
aiming for with the "no this pointer" requirement? Again, I could be
missing something, but this seems ambiguous/unresolvable to me.

That's why you need the extra syntax which specifies the actual type to
call the method on.
 
Frank Oquendo said:
Static members cannot be virtual. That makes sense when you think about it.
I've never heard of the concept of static polymorphism.

Templates (or generics in C# parlance) are actually pretty close to what you
could call static polymorphism. Consider this imaginary syntax:

interface ISingleton<T>
{
static T Instance();
}

class X : ISingleton<X>
{
static X x_ = new X();
static X Instance() { return x_; }
}

Makes perfect sense eh?

Sami
 
Why can't I have a static abstract method in C#?

My intention is to have a class-level method that returns a string to
supply information about inherited classes, and it is natural to make
this static so that I don't need an instance in order to call it.
However, because my class model is using a common base class, I need to
make it abstract too, so that inherited classes are forced to implement
it.

Am I doing something that can be done another way, or considered 'ugly'
in OOD? Or is C# being inconsiderate?

Thanks to everyone who replied and explained this to me. I now realise
that what I was trying to do doesn't actually have a use.

I will now implement this part of my design with non-static, abstract
virtual methods. My intention was to enable the user to select a
particular inherited class at run-time, in order to control behaviour. To
this end, I wanted each class to supply a description of what it does, so
that I could populate a drop-down - but I didn't want to instantiate
anything at that point, because of the overheads that might imply.

I can't think of an easy answer, so I think I'm just going to have to
instantiate an object of each class, in order to get its class description
returned to me. Or have I missed something? (I don't know anything about
System.Type etc.)
 
You've missed using Metadata to mark you types. You can create attributes and
attach them to your
types, then look for those attributes, rather than actually instantiating the
type in question. You can't
require attributes though, so if they aren't supplied then you wouldn't be able
to get the description.
However, having attributes as a requirement for loading a particular class is
very similar to something
I've blogged about in the past.

http://weblogs.asp.net/justin_rogers/archive/2004/02/08/69846.aspx

The posting has a pointer to my plug-in article on different ways to investigate
assemblies and locate
plug-ins. I'm guessing another article will be related to getting information
about each of the plug-ins
prior to loading, and again there will be a number of ways (using attributes to
mark the class, using
attributes to mark a static method that returns plug-in information, or any
number of other methods).
What you really want is something enforceable, and while attributes aren't
enforceable you can refuse
to load a given type if it doesn't support the attributes you require in order
to run.
 
You've missed using Metadata to mark you types. You can create
attributes and
attach them to your
types, then look for those attributes, rather than actually
instantiating the
type in question. You can't
require attributes though, so if they aren't supplied then you wouldn't
be able
to get the description.
However, having attributes as a requirement for loading a particular
class is
very similar to something
I've blogged about in the past.

http://weblogs.asp.net/justin_rogers/archive/2004/02/08/69846.aspx

The posting has a pointer to my plug-in article on different ways to
investigate
assemblies and locate
plug-ins. I'm guessing another article will be related to getting
information
about each of the plug-ins
prior to loading, and again there will be a number of ways (using
attributes to
mark the class, using
attributes to mark a static method that returns plug-in information, or
any
number of other methods).
What you really want is something enforceable, and while attributes
aren't
enforceable you can refuse
to load a given type if it doesn't support the attributes you require in
order
to run.

That's very interesting, thanks! I shall investigate that approach
further.
 
Mike,
For arguments sake lets look at it practically on how you'd see
it being used

abstract class A {
public static abstract string functionA();
}

class B : A {
public static string functionA() {
return "B";
}
}

Now if your're going to be calling it...
would'nt you be calling it

B.functionA();

at which point wouldnt you already be knowing what type it is? because
you're calling the function explicitly *B.*. Let me know if I din't
understand your requirement, hope that helps

Sorry for this very late reply.

Yes, I would be calling it using class B, but my reason for wanting static
abstract has nothing to do with polymorphism, really.

I want 'static' because I want a class-scope method.
I want 'abstract' because I want to force the derived classes to implement
that method.

I think that's the simplest summation I can manage. Does it help?
 
Mike said:
On Fri, 13 Feb 2004 10:51:57 -0600, Dilip Krishnan
[skipped]

Sorry for this very late reply.

Yes, I would be calling it using class B, but my reason for wanting
static abstract has nothing to do with polymorphism, really.

I want 'static' because I want a class-scope method.
I want 'abstract' because I want to force the derived classes to
implement that method.

I think that's the simplest summation I can manage. Does it help?
Hi, Mike.

'static abstract' is not what you need. Because 'abstract' is not a force to implement method somewhere.
Because 'abstract' is a polymorphic tool and not 'compiler control' tool.

How to force classes implement some static method:
public class A
{
public static void method();
}

public class B
{
//public static void method(); //let it not implement this method
}

public class ThisClassForcesThoseMethodsToBeImplemented
{
/// objects of this class will never be created.
ThisClassForcesThoseMethodsToBeImplemented(){}

/// Try to call me :))
public void unreferencedMethod()
{
A.method();
B.method(); /// this will give you an error if you do not implement method() at class scope
SomeOtherClassYouWant.method();
}
}

/// Easy to maitain (if you _really_ need that!). Just add a class you want or remove. No polymorphism,
/// no headache.

That's all! You really do not want that 'static abstract' ;)
 
Back
Top