abstract static?

  • Thread starter Thread starter Chris Capel
  • Start date Start date
C

Chris Capel

What is the rationale behind the decision not to allow abstract static class
members? It doesn't seem like it's a logically contradictory concept, or
that the implementation would be difficult or near-impossible. It seems like
it would be useful. In fact, there's a place in my code that I could make
good use of it. So why not?

Chris
 
If it is static, then it does not really belong to any
instance of a class. Therefore, it cannot be inherited.

Tu-Thach
 
Chris,

The problem with this comes from the base type (abstract) not knowing
which derived type to go to for the implementation. For example, if you had
the following:

public abstract class Base
{
public static abstract void DoSomething();
}

Then you had a derived class like this:

public class Derived : Base
{
public static override void DoSomething()
{}
}

How would you indicate that you want to use the implementation in
Derived? I can have many implementations of DoSomething, and if I want to
call through the Base class, there is no way of indicating which derived
class to use.

In order to get around this now, you should use a class factory pattern
combined with a singleton pattern. The singleton pattern is used to mimic
static behavior, while the class factory pattern is used to indicate the
derived type to use (while returning the base type).

Hope this helps.
 
I've got the exact same problem. I'd like to make sure all of my subclasses
have a certain static variable.

Look at the topic 'Static variables and inheritance'
 
The problem with this comes from the base type (abstract) not knowing
which derived type to go to for the implementation.
How would you indicate that you want to use the implementation in
Derived? I can have many implementations of DoSomething, and if I want to
call through the Base class, there is no way of indicating which derived
class to use.

Fair enough. But I see having an abstract static member as more of a way to
guarantee that any non-abstract subclass will have implemented that member,
not as a way to accomplish polymorphism at all. For instance:

public abstract class ImporterBase {
protected abstract string[] ExtensionsSupported { get; }
public abstract void ImportFile(string path);
}

public class CsvImporter : ImporterBase {
protected override string[] ExtensionsSupported {
get {
return new string[] {"csv"};
}
}
public override void ImportFile(string path) {
//some stuff
}
}

Now, the only way this could really benefit a programmer, it seems, is when
reflection is used to look at the derived class. For instance:

public abstract class ImporterBase {
//stuff from above definition

public static ImporterBase GetImporter(string extension) {
Type[] types = Assembly.GetExecutingAssembly().GetTypes(); // or
could come from other files
foreach (Type t in types) {
if (t.IsSubclassOf(typeof(IssueImporter))) {
string[] exts =
(string[])t.GetProperty("Extension").GetValue(null, null);
foreach (string e in exts)
if (e == extensionToFind)
return (ImporterBase)Activator.CreateInstance(t);
}
}
return null;
}
}

Maybe this use-case is too uncommon and narrow to justify a language
decision like that, but it sure would be nice for me.

But then, I can just use attributes.

Chris
 
Correction to my code:

public abstract class ImporterBase {
protected abstract static string[] ExtensionsSupported {get;}
...

public class CsvImporter : ImporterBase {
protected static override string[] ExtensionsSupported {
...


Chris Capel said:
The problem with this comes from the base type (abstract) not knowing
which derived type to go to for the implementation.
How would you indicate that you want to use the implementation in
Derived? I can have many implementations of DoSomething, and if I want to
call through the Base class, there is no way of indicating which derived
class to use.

Fair enough. But I see having an abstract static member as more of a way to
guarantee that any non-abstract subclass will have implemented that member,
not as a way to accomplish polymorphism at all. For instance:

public abstract class ImporterBase {
protected abstract string[] ExtensionsSupported { get; }
public abstract void ImportFile(string path);
}

public class CsvImporter : ImporterBase {
protected override string[] ExtensionsSupported {
get {
return new string[] {"csv"};
}
}
public override void ImportFile(string path) {
//some stuff
}
}

Now, the only way this could really benefit a programmer, it seems, is when
reflection is used to look at the derived class. For instance:

public abstract class ImporterBase {
//stuff from above definition

public static ImporterBase GetImporter(string extension) {
Type[] types = Assembly.GetExecutingAssembly().GetTypes(); // or
could come from other files
foreach (Type t in types) {
if (t.IsSubclassOf(typeof(IssueImporter))) {
string[] exts =
(string[])t.GetProperty("Extension").GetValue(null, null);
foreach (string e in exts)
if (e == extensionToFind)
return (ImporterBase)Activator.CreateInstance(t);
}
}
return null;
}
}

Maybe this use-case is too uncommon and narrow to justify a language
decision like that, but it sure would be nice for me.

But then, I can just use attributes.

Chris
 
More correction (::sheepish grin::)

On line 3 of ImporterBase.GetImporter it should read

if (t.IsSubclassOf(typeof(ImporterBase))) {

Sorry.

Chris Capel said:
The problem with this comes from the base type (abstract) not knowing
which derived type to go to for the implementation.
How would you indicate that you want to use the implementation in
Derived? I can have many implementations of DoSomething, and if I want to
call through the Base class, there is no way of indicating which derived
class to use.

Fair enough. But I see having an abstract static member as more of a way to
guarantee that any non-abstract subclass will have implemented that member,
not as a way to accomplish polymorphism at all. For instance:

public abstract class ImporterBase {
protected abstract string[] ExtensionsSupported { get; }
public abstract void ImportFile(string path);
}

public class CsvImporter : ImporterBase {
protected override string[] ExtensionsSupported {
get {
return new string[] {"csv"};
}
}
public override void ImportFile(string path) {
//some stuff
}
}

Now, the only way this could really benefit a programmer, it seems, is when
reflection is used to look at the derived class. For instance:

public abstract class ImporterBase {
//stuff from above definition

public static ImporterBase GetImporter(string extension) {
Type[] types = Assembly.GetExecutingAssembly().GetTypes(); // or
could come from other files
foreach (Type t in types) {
if (t.IsSubclassOf(typeof(IssueImporter))) {
string[] exts =
(string[])t.GetProperty("Extension").GetValue(null, null);
foreach (string e in exts)
if (e == extensionToFind)
return (ImporterBase)Activator.CreateInstance(t);
}
}
return null;
}
}

Maybe this use-case is too uncommon and narrow to justify a language
decision like that, but it sure would be nice for me.

But then, I can just use attributes.

Chris
 
Hi Chris,

I dont see any reason to have this abstract member in the base class. You
will get the right value anyway.
Since you have the Type object to some class
(string[])t.GetProperty("Extension").GetValue(null, null); will get the
property's value of this class regardless of whether you have defined that
abstract method in the base class or not.


B\rgds
100



Chris Capel said:
The problem with this comes from the base type (abstract) not knowing
which derived type to go to for the implementation.
How would you indicate that you want to use the implementation in
Derived? I can have many implementations of DoSomething, and if I want to
call through the Base class, there is no way of indicating which derived
class to use.

Fair enough. But I see having an abstract static member as more of a way to
guarantee that any non-abstract subclass will have implemented that member,
not as a way to accomplish polymorphism at all. For instance:

public abstract class ImporterBase {
protected abstract string[] ExtensionsSupported { get; }
public abstract void ImportFile(string path);
}

public class CsvImporter : ImporterBase {
protected override string[] ExtensionsSupported {
get {
return new string[] {"csv"};
}
}
public override void ImportFile(string path) {
//some stuff
}
}

Now, the only way this could really benefit a programmer, it seems, is when
reflection is used to look at the derived class. For instance:

public abstract class ImporterBase {
//stuff from above definition

public static ImporterBase GetImporter(string extension) {
Type[] types = Assembly.GetExecutingAssembly().GetTypes(); // or
could come from other files
foreach (Type t in types) {
if (t.IsSubclassOf(typeof(IssueImporter))) {
string[] exts =
(string[])t.GetProperty("Extension").GetValue(null, null);
foreach (string e in exts)
if (e == extensionToFind)
return (ImporterBase)Activator.CreateInstance(t);
}
}
return null;
}
}

Maybe this use-case is too uncommon and narrow to justify a language
decision like that, but it sure would be nice for me.

But then, I can just use attributes.

Chris
 
Hi Nicholas,
Beside what you said I would like to add something:

You can't have polymorphism via reflection.

Consider this:

Case 1:

Type t = someObject.GetType();

In MSDN we can read the following for Object.GetType method:
"
.....
Return Value
The Type instance that represents the exact runtime type of the current
instance.
......
"
So polymorphism can't play any role here because we are going to call the
methods of the *actual* run-time type.

Well, we can get a type object for one of the parent classes and try to call
say
Type t = typeof(ABaseForSomeObjectsClass)
t.GetProperty("PropName").GetValue(someObject,.....);
And to say that we really need polymorphism here. It doesn't make sence,
though. Since we have the reference to the object we always can call:
someObject.GetType() to get the right type object. And we are back to square
one.

Case2:

Type t = typeof(SomeType);

If we need to access instance method we need to have reference to the actual
object. You already have my *Case1*...

If we we want to use a static member.... Well, we have already specified
the type. There is no room for polymorphism again. Mainly because we don't
have an object that has a *real* type.

And to back up my point here there is some example of this.
//I assume here that *static abstract* exist
class Base
{
public abstract static void Foo();
}

class Derived1: Base
{
public override static void Foo()
{
....
}
}

class Derived2: Base
{
public override static void Foo()
{
....
}
}

Somewhere in the code

Type t = typeof(Base)

So now, if we try to call Foo via reflection, which one should be called
Derived1.Foo or Derived2.Foo?

In this case polymorphism is not possible again.

Any other way to obtain a type object belongs to one of those two cases I
believe.

The real problem is that Type objects *represent* tha given type. They are
not references to actual meta-type objects (which in fact exist internally)

B\rgds
100
Nicholas Paldino said:
Chris,

In a previous thread, these reasonings were given as well. My believe
is that unless you can achieve polymorphism, then you shouldn't introduce a
new language construct like this which will need additional support through
another mechanism. Abstract already has a very well-defined meaning, and
that meaning would be diluted though this use of it.

If you have to resort to reflection anyways to do this, then you can
easily get around this by creating a custom attribute and applying it to the
static method that you want to represent your "overridden" method in another
class. Also, I think that using the design patterns pointed out represent a
very clean solution to the issue as well. Having to use a language
construct in conjunction with reflection is rather dirty. If I had to use
reflection to call overridden methods on derived classes, I don't think that
I would like it too much.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

want
to
call through the Base class, there is no way of indicating which derived
class to use.

Fair enough. But I see having an abstract static member as more of a way to
guarantee that any non-abstract subclass will have implemented that member,
not as a way to accomplish polymorphism at all. For instance:

public abstract class ImporterBase {
protected abstract string[] ExtensionsSupported { get; }
public abstract void ImportFile(string path);
}

public class CsvImporter : ImporterBase {
protected override string[] ExtensionsSupported {
get {
return new string[] {"csv"};
}
}
public override void ImportFile(string path) {
//some stuff
}
}

Now, the only way this could really benefit a programmer, it seems, is when
reflection is used to look at the derived class. For instance:

public abstract class ImporterBase {
//stuff from above definition

public static ImporterBase GetImporter(string extension) {
Type[] types = Assembly.GetExecutingAssembly().GetTypes(); // or
could come from other files
foreach (Type t in types) {
if (t.IsSubclassOf(typeof(IssueImporter))) {
string[] exts =
(string[])t.GetProperty("Extension").GetValue(null, null);
foreach (string e in exts)
if (e == extensionToFind)
return (ImporterBase)Activator.CreateInstance(t);
}
}
return null;
}
}

Maybe this use-case is too uncommon and narrow to justify a language
decision like that, but it sure would be nice for me.

But then, I can just use attributes.

Chris
 
100,

There wasn't an implication that you can have polymorphism through
Reflection, but rather, to gain the polymorphism on static members, you
would have to use a combination of reflection and the abstract keyword.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

100 said:
Hi Nicholas,
Beside what you said I would like to add something:

You can't have polymorphism via reflection.

Consider this:

Case 1:

Type t = someObject.GetType();

In MSDN we can read the following for Object.GetType method:
"
....
Return Value
The Type instance that represents the exact runtime type of the current
instance.
.....
"
So polymorphism can't play any role here because we are going to call the
methods of the *actual* run-time type.

Well, we can get a type object for one of the parent classes and try to call
say
Type t = typeof(ABaseForSomeObjectsClass)
t.GetProperty("PropName").GetValue(someObject,.....);
And to say that we really need polymorphism here. It doesn't make sence,
though. Since we have the reference to the object we always can call:
someObject.GetType() to get the right type object. And we are back to square
one.

Case2:

Type t = typeof(SomeType);

If we need to access instance method we need to have reference to the actual
object. You already have my *Case1*...

If we we want to use a static member.... Well, we have already specified
the type. There is no room for polymorphism again. Mainly because we don't
have an object that has a *real* type.

And to back up my point here there is some example of this.
//I assume here that *static abstract* exist
class Base
{
public abstract static void Foo();
}

class Derived1: Base
{
public override static void Foo()
{
....
}
}

class Derived2: Base
{
public override static void Foo()
{
....
}
}

Somewhere in the code

Type t = typeof(Base)

So now, if we try to call Foo via reflection, which one should be called
Derived1.Foo or Derived2.Foo?

In this case polymorphism is not possible again.

Any other way to obtain a type object belongs to one of those two cases I
believe.

The real problem is that Type objects *represent* tha given type. They are
not references to actual meta-type objects (which in fact exist internally)

B\rgds
100
in message news:[email protected]...
Chris,

In a previous thread, these reasonings were given as well. My believe
is that unless you can achieve polymorphism, then you shouldn't
introduce
a
new language construct like this which will need additional support through
another mechanism. Abstract already has a very well-defined meaning, and
that meaning would be diluted though this use of it.

If you have to resort to reflection anyways to do this, then you can
easily get around this by creating a custom attribute and applying it to the
static method that you want to represent your "overridden" method in another
class. Also, I think that using the design patterns pointed out
represent
a
very clean solution to the issue as well. Having to use a language
construct in conjunction with reflection is rather dirty. If I had to use
reflection to call overridden methods on derived classes, I don't think that
I would like it too much.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Chris Capel said:
The problem with this comes from the base type (abstract) not knowing
which derived type to go to for the implementation.

How would you indicate that you want to use the implementation in
Derived? I can have many implementations of DoSomething, and if I
want
to
call through the Base class, there is no way of indicating which derived
class to use.

Fair enough. But I see having an abstract static member as more of a
way
to
guarantee that any non-abstract subclass will have implemented that member,
not as a way to accomplish polymorphism at all. For instance:

public abstract class ImporterBase {
protected abstract string[] ExtensionsSupported { get; }
public abstract void ImportFile(string path);
}

public class CsvImporter : ImporterBase {
protected override string[] ExtensionsSupported {
get {
return new string[] {"csv"};
}
}
public override void ImportFile(string path) {
//some stuff
}
}

Now, the only way this could really benefit a programmer, it seems, is when
reflection is used to look at the derived class. For instance:

public abstract class ImporterBase {
//stuff from above definition

public static ImporterBase GetImporter(string extension) {
Type[] types = Assembly.GetExecutingAssembly().GetTypes(); // or
could come from other files
foreach (Type t in types) {
if (t.IsSubclassOf(typeof(IssueImporter))) {
string[] exts =
(string[])t.GetProperty("Extension").GetValue(null, null);
foreach (string e in exts)
if (e == extensionToFind)
return (ImporterBase)Activator.CreateInstance(t);
}
}
return null;
}
}

Maybe this use-case is too uncommon and narrow to justify a language
decision like that, but it sure would be nice for me.

But then, I can just use attributes.

Chris
 
Chris,

The singleton pattern would assure that only one instance of an object
exists. You would set the boundaries of this limitation to the app-domain,
which is simple, because your singleton will be stored in a static member.

So, you define your base class or interface which has the methods you
want to expose (the static ones, but it will be exposed through a singular
instance, which is the equivalent of static), like this:

public interface IMyInterface
{
void DoSomething();
}

Or, you could make it a base class or abstract class, it doesn't matter,
as long as you have a type that is extensible.

Then, you would implement the interfaces/abstract classs wherever you
wish. Once you have that, you would have a class factory, which would be
implemented as a static method somewhere.

public class MyClassFactory
{
// Have a hashtable which will have the instances that have been
created.
private Hashtable sobjInstances = new Hashtable();

// Will return the singular instance of an object given a key, which you
will supply.
public static IMyInterface GetInstance(object key)
{
// Check for the key in the hashtable. If it doesn't exist, then
// create it and put it in the hashtable.
if (!sobjInstances.ContainsKey(key))
// Create an instance here based on information in the key.
sobjInstances[key] = // Create new instance here.

// Return the value in the hashtable.
return (IMyInterface) sobjInstances[key];
}
}

So, in your case, your key could be the name of an assembly and class
that you know implements the appropriate interface. Of course, you could
use attributes to indicate which classes you should use, but you can use
reflection to scan through all of the types and determine which types
implement which interfaces or derive from which base classes. How much of
this you place into your class factory is up to you.

Using this, you get polymorphism and singular instance (the same as
static) semantics.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Chris Capel said:
"Also, I think that using the design patterns pointed out represent a very
clean solution to the issue as well."

Could you rough out how to apply the singleton/class factory pattern to my
scenario? How would I use these methods to make sure that every class
derived from ImporterBase provided the extensions that it can import? Keep
in mind that in my situation, I'm loading these implementations of
ImporterBase from assemblies located at runtime, like this:

string[] files = Directory.GetFiles(Environment.CurrentDirectory,
"*company.Application.Importer*dll*");
foreach (string s in files) {
Assembly a = Assembly.LoadFile(s);
//etc
}

Right now I use attributes, like this:

[AttributeUsage(AttributeTargets.Class)]
public class ExtensionsAttribute : Attribute {
public readonly string[] Extensions;
public ExtensionsAttribute(string[] extensions) {
Extensions = extensions;
}
}

[Extensions(new string[] {"csv"})]
public class CsvImporter : IssueImporter {
...

foreach (Type t in types) {
if (t.IsSubclassOf(typeof(ImporterBase))) {
ExtensionsAttribute[] exts =
(ExtensionsAttribute[])t.GetCustomAttributes(typeof(ExtensionsAttribute),
false);
if (exts.Length > 0)
foreach (string e in exts[0].Extensions)
if (e == extension)
return (ImporterBase)Activator.CreateInstance(t);
}
}

Would your class factory/singleton patterns provide a better way to do this?

Chris


in message news:[email protected]...
Chris,

In a previous thread, these reasonings were given as well. My believe
is that unless you can achieve polymorphism, then you shouldn't
introduce
a
new language construct like this which will need additional support through
another mechanism. Abstract already has a very well-defined meaning, and
that meaning would be diluted though this use of it.

If you have to resort to reflection anyways to do this, then you can
easily get around this by creating a custom attribute and applying it to the
static method that you want to represent your "overridden" method in another
class. Also, I think that using the design patterns pointed out
represent
 
I thought one of the properties of a singleton was that you can't derive
from it (private constructor), and if you can you get more than one instance
of the base class


Nicholas Paldino said:
Chris,

The problem with this comes from the base type (abstract) not knowing
which derived type to go to for the implementation. For example, if you had
the following:

public abstract class Base
{
public static abstract void DoSomething();
}

Then you had a derived class like this:

public class Derived : Base
{
public static override void DoSomething()
{}
}

How would you indicate that you want to use the implementation in
Derived? I can have many implementations of DoSomething, and if I want to
call through the Base class, there is no way of indicating which derived
class to use.

In order to get around this now, you should use a class factory pattern
combined with a singleton pattern. The singleton pattern is used to mimic
static behavior, while the class factory pattern is used to indicate the
derived type to use (while returning the base type).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Chris Capel said:
What is the rationale behind the decision not to allow abstract static class
members? It doesn't seem like it's a logically contradictory concept, or
that the implementation would be difficult or near-impossible. It seems like
it would be useful. In fact, there's a place in my code that I could make
good use of it. So why not?

Chris
 
My point is that there is no case when you ever need to use plymorphism when
you use reflection.


Nicholas Paldino said:
100,

There wasn't an implication that you can have polymorphism through
Reflection, but rather, to gain the polymorphism on static members, you
would have to use a combination of reflection and the abstract keyword.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

100 said:
Hi Nicholas,
Beside what you said I would like to add something:

You can't have polymorphism via reflection.

Consider this:

Case 1:

Type t = someObject.GetType();

In MSDN we can read the following for Object.GetType method:
"
....
Return Value
The Type instance that represents the exact runtime type of the current
instance.
.....
"
So polymorphism can't play any role here because we are going to call the
methods of the *actual* run-time type.

Well, we can get a type object for one of the parent classes and try to call
say
Type t = typeof(ABaseForSomeObjectsClass)
t.GetProperty("PropName").GetValue(someObject,.....);
And to say that we really need polymorphism here. It doesn't make sence,
though. Since we have the reference to the object we always can call:
someObject.GetType() to get the right type object. And we are back to square
one.

Case2:

Type t = typeof(SomeType);

If we need to access instance method we need to have reference to the actual
object. You already have my *Case1*...

If we we want to use a static member.... Well, we have already specified
the type. There is no room for polymorphism again. Mainly because we don't
have an object that has a *real* type.

And to back up my point here there is some example of this.
//I assume here that *static abstract* exist
class Base
{
public abstract static void Foo();
}

class Derived1: Base
{
public override static void Foo()
{
....
}
}

class Derived2: Base
{
public override static void Foo()
{
....
}
}

Somewhere in the code

Type t = typeof(Base)

So now, if we try to call Foo via reflection, which one should be called
Derived1.Foo or Derived2.Foo?

In this case polymorphism is not possible again.

Any other way to obtain a type object belongs to one of those two cases I
believe.

The real problem is that Type objects *represent* tha given type. They are
not references to actual meta-type objects (which in fact exist internally)

B\rgds
100
in message news:[email protected]...
Chris,

In a previous thread, these reasonings were given as well. My believe
is that unless you can achieve polymorphism, then you shouldn't
introduce
a
new language construct like this which will need additional support through
another mechanism. Abstract already has a very well-defined meaning, and
that meaning would be diluted though this use of it.

If you have to resort to reflection anyways to do this, then you can
easily get around this by creating a custom attribute and applying it
to
the
static method that you want to represent your "overridden" method in another
class. Also, I think that using the design patterns pointed out
represent
a
very clean solution to the issue as well. Having to use a language
construct in conjunction with reflection is rather dirty. If I had to use
reflection to call overridden methods on derived classes, I don't
think
that
I would like it too much.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

The problem with this comes from the base type (abstract) not
knowing
which derived type to go to for the implementation.

How would you indicate that you want to use the implementation in
Derived? I can have many implementations of DoSomething, and if I want
to
call through the Base class, there is no way of indicating which derived
class to use.

Fair enough. But I see having an abstract static member as more of a way
to
guarantee that any non-abstract subclass will have implemented that
member,
not as a way to accomplish polymorphism at all. For instance:

public abstract class ImporterBase {
protected abstract string[] ExtensionsSupported { get; }
public abstract void ImportFile(string path);
}

public class CsvImporter : ImporterBase {
protected override string[] ExtensionsSupported {
get {
return new string[] {"csv"};
}
}
public override void ImportFile(string path) {
//some stuff
}
}

Now, the only way this could really benefit a programmer, it seems, is
when
reflection is used to look at the derived class. For instance:

public abstract class ImporterBase {
//stuff from above definition

public static ImporterBase GetImporter(string extension) {
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
//
or
could come from other files
foreach (Type t in types) {
if (t.IsSubclassOf(typeof(IssueImporter))) {
string[] exts =
(string[])t.GetProperty("Extension").GetValue(null, null);
foreach (string e in exts)
if (e == extensionToFind)
return (ImporterBase)Activator.CreateInstance(t);
}
}
return null;
}
}

Maybe this use-case is too uncommon and narrow to justify a language
decision like that, but it sure would be nice for me.

But then, I can just use attributes.

Chris
 
Since I'm still researching alot of what I was babbling about, do you know
of any languages that support the level of a contract that requires
specification of constructors and the like? I've yet to find one that
explicit.
I'm still playing with some random syntaxes to simplify(or remove the need
for) reflection in many cases and allow a specification of a number of
things an object needs to be aware of...not that it'll ever get implemented,
but I find it an interesting research project
 
Richard Cook said:
Not sure - languages like Python, Rexx have metaclass facilities, so you can
define a metaclass and tell a class what it's metaclass is, so you can add
methods to the class, but these are dynamically typed languages.
Hrmm, I will have to research these further, I havn't done much reading on
python.
AspectJ (AOP for Java) allows you among other things to detect and issue
errors at compile time for eg use of public fields, use of console
stdout/stderr, static variables in EJBs, but haven't seen that it can detect
the non existence of something, like a constructor or static method. It can
introduce them, ie plonk a definition inside a class or class hierarchy, or
give default implementations for interface methods, but not the same thing
as simply requiring one to be defined. Don't know if there's an AspectC# or
AspectN equivalent.
My goal here is to be able to provide a flexible contract between two,
otherwise unrelated modules (think plugins or loosely coupled modules in a
large app) in metadata, not using a extension tool(well, eventually, I
suspect if I ever put this idea into code it will be a C# class generator
that creates a class that does what I want, I havn't the skill to try to add
it to the runtime, get no compiler help there tho). Something akin to
requiring a class provides a given constructor, a bundle of required
interfaces (sort of a Interface Interface, in other words, to interact with
me you ahve to implement X, Y, and Z), static methods, perhaps even things
like the permissions that definitly will and definatly won't be allowed,
attributes that are expected, exceptions both ends must handle, pre & post
conditions on methods, etc. Basically anything that needs to be known to
both sides and that should exist in both a compiler and runtime enforcable
way and in a manner that is self documenting.
But, it is just an experiment and i'm sure there are lots of problems with
the approach(and that its probably been done before, i'm just not having any
luck finding it)
Anyway, i'll look into AspectJ and AOP in general, see what it can do.

After doing a bit of research, I found a project called AspectC# [1], going
to dive into the dissertation that backs it later today, not up to that much
reading quite yet.

[1] http://www.dsg.cs.tcd.ie/index.php?category_id=169
 
Without wanting to harp on about C++ templates, they do do the job, but
clearly they do have the drawback that there is not an explicit listing of
what is required from a class, it's implicit from the various things that
you ask the class to do.

This does mean, however, that the specification of requirements is bound
inextricably with its usage. This gives us a couple of advantages:

1) The specification can't go 'over-the-top' asking for requirements that
are never used and therefore wasting implementer's time and causing code
bloat. The C++ template mechanism is very good at not forming instantiations
that can never be called.

2) There is no risk that (as there would be with specification plus
reflection) that at runtime a requirement will be discovered that was
missing from the specification.

Templates give a full list of non-compliance at compile-time. The problem is
that this list is unclear and scattered about the full error list. It might
be useful to develop a tool which strips out all those non-compliances from
the error list and presents a summary of why a class fails to comply. (Some
C++ compilers may already do this.)

Regards,

Jasper Kent.
 
Jasper Kent said:
Without wanting to harp on about C++ templates, they do do the job, but
clearly they do have the drawback that there is not an explicit listing of
what is required from a class, it's implicit from the various things that
you ask the class to do.
Problem is, I personally don't really care for templates and find them to
generally cause me more trouble than they solve(I HATE getting errors in
source files i didn't even know existed and I seem to have a knack for
breaking templated code). I never liked C++ in the first place (used C than
C#, skipped the C++ nightmare for the most part), and templates always made
the language less pleasent...I do not think it would be a good thing to
introduce that kinda trouble into C# or the framework as a whole. Plus,
templates don't provide any sort of easy self-documentation nor are they
easy to write and read in a single sitting, in the concept I have sitting in
my head, you could just sit down and scan about 40 lines of source max and
understand what is required of you and what restrictions sit on you (ie,
what permissions will exist for the module).
Anyway, I don't want to start a C++ template discussion, thats just my
biased opinion on a technology I do not fully understand. ;)
This does mean, however, that the specification of requirements is bound
inextricably with its usage. This gives us a couple of advantages:

1) The specification can't go 'over-the-top' asking for requirements that
are never used and therefore wasting implementer's time and causing code
bloat. The C++ template mechanism is very good at not forming instantiations
that can never be called.

In the design I want, there would be a few new ways to add functionality
thats not needed, most notably the instance of forcing attributes or
something where the loader doesn't check for them (although the contractual
construct probably would on load aswell...not sure), but nothing that is to
big of a deal. As it stands the biggest problem is when interfaces specify a
method that the external loader never bothers to use.
2) There is no risk that (as there would be with specification plus
reflection) that at runtime a requirement will be discovered that was
missing from the specification.

I'm not quite sure what you mean here, part of the goal of this crazy
experiment is to provide a construct that does the reflection nessecery to
verify and return the object specified, to both provide a specification and
to remove the need to write similar reflection code for every plugin or
module loader you write. It wouldn't be too difficult to design a class gen
that produced a factory or something that follows a set of rules and
performs the reflection and a implementing class, that would be my first
goal if I ever get teh design up and moving, but runtime & compiler level
enforcement would be the penultimate.
 
I traced through the responses to the original question, and while I
might have missed something, I feel Chris Capel's question was never
really answered. There were responses about how to do what Chris
wants to do differently, responses that argued the idea, even a nod to
contracts--which I thought missed the whole point.

In the example given, a contract has already been established--in the
form of an abstract class.

I have my own design issue, which brought me to this group in the
first place. I am working on a large number of domain and data mapper
pattern objects. Some of my mappers can handle more than one domain
object, because the domain objects are subclassed.

In order to use a mapper registry (factory) to produce them, I decided
to have each mapper track its mapped types:

public abstract class BaseDataMapper
{
public abstract Type[] MappedTypes{ get ; }
...
}

I think it is reasonable that the author of a mapper should decide
which objects that mapper can map into persistent storage:

public class NamedObjectMapper : BaseDataMapper
{
public override Type[] MappedTypes
{
get{ return new Type[]{ typeof( ServiceType ), typeof(
UnitType ) } ; )
}
}

Now, during registration of the above mapper type in a factory, I need
some way of registering the supported types--from:

mapperRegistry.GetInstanceFor( ServiceType )

I expect the factory to produce the exact mapper I need. Unless the
property described above is also abstract, I cannot do this without
creating an instance of the mapper during registration. Five mappers?
No big deal. Four hundred mappers in a service layer? No way I want
to create an instance of all of those during registration. Not in an
environment where new domain objects and mappers can be added at
runtime, and their types registered.

And this is the thing: attributes? Come on. The issue here is to
force the mapper author to comply with the contract.

So--why not abstract statics?
 
Jonathan Malek said:
I traced through the responses to the original question, and while I
might have missed something, I feel Chris Capel's question was never
really answered. There were responses about how to do what Chris
wants to do differently, responses that argued the idea, even a nod to
contracts--which I thought missed the whole point.

In the example given, a contract has already been established--in the
form of an abstract class.

I have my own design issue, which brought me to this group in the
first place. I am working on a large number of domain and data mapper
pattern objects. Some of my mappers can handle more than one domain
object, because the domain objects are subclassed.

In order to use a mapper registry (factory) to produce them, I decided
to have each mapper track its mapped types:

public abstract class BaseDataMapper
{
public abstract Type[] MappedTypes{ get ; }
...
}

I think it is reasonable that the author of a mapper should decide
which objects that mapper can map into persistent storage:

public class NamedObjectMapper : BaseDataMapper
{
public override Type[] MappedTypes
{
get{ return new Type[]{ typeof( ServiceType ), typeof(
UnitType ) } ; )
}
}

Now, during registration of the above mapper type in a factory, I need
some way of registering the supported types--from:

mapperRegistry.GetInstanceFor( ServiceType )

I expect the factory to produce the exact mapper I need. Unless the
property described above is also abstract, I cannot do this without
creating an instance of the mapper during registration. Five mappers?
No big deal. Four hundred mappers in a service layer? No way I want
to create an instance of all of those during registration. Not in an
environment where new domain objects and mappers can be added at
runtime, and their types registered.

And this is the thing: attributes? Come on. The issue here is to
force the mapper author to comply with the contract.

So--why not abstract statics?
Because they are messy, if you read everything posted there were a number of
arguments. The most important one is that there is no polymorphic way to
access static methods, you are forced to use reflection and any feature that
REQUIRES reflection to use it is not something that should exist, IMHO.
I would not ever use statics in that manner, attributes exist for just that
purpose(among others, of course). I do however think that a contract that
can handle required attributes should exist, that is a very different matter
entirely.
 
Daniel,
Correct me if I am wrong, but there is no polymorphic way to access static methods in C# because C# doesn't support virtual static methods. Other languages do (Delphi, for one). In other words, the most important argument for not having abstract statics is that C# doesn't support them. So, I figure I am missing something.
I have read quite a bit on this topic in other lists (the comp.std.c++ list had what seems like a semi-annual celebration on the issue for several years), trying to understand what the issue is. I suppose I don't quite see the messy aspect of it all. Everyone raises the same issue--"virtual static?? Why ever would you want to do such a thing? Oh I see--well, you know, you could do that this way, or that way..." That's not really an answer. It can be done, it solves a particular design problem (I've written one up below that I feel can only be solved this way--or, as you mention, with contract-enforced attributes), and other languages have shown that.
So, is there something beneath it all, say in the CIL/CLS/CTS/CLR that prohibits such a thing? Better question--is it possible to introduce CTS-compliant virtual statics? I suppose if the answer to that is no, then it is pointless wondering why C# doesn't support them.
Jonathan Malek said:
I traced through the responses to the original question, and while I
might have missed something, I feel Chris Capel's question was never
really answered. There were responses about how to do what Chris
wants to do differently, responses that argued the idea, even a nod to
contracts--which I thought missed the whole point.

In the example given, a contract has already been established--in the
form of an abstract class.

I have my own design issue, which brought me to this group in the
first place. I am working on a large number of domain and data mapper
pattern objects. Some of my mappers can handle more than one domain
object, because the domain objects are subclassed.

In order to use a mapper registry (factory) to produce them, I decided
to have each mapper track its mapped types:

public abstract class BaseDataMapper
{
public abstract Type[] MappedTypes{ get ; }
...
}

I think it is reasonable that the author of a mapper should decide
which objects that mapper can map into persistent storage:

public class NamedObjectMapper : BaseDataMapper
{
public override Type[] MappedTypes
{
get{ return new Type[]{ typeof( ServiceType ), typeof(
UnitType ) } ; )
}
}

Now, during registration of the above mapper type in a factory, I need
some way of registering the supported types--from:

mapperRegistry.GetInstanceFor( ServiceType )

I expect the factory to produce the exact mapper I need. Unless the
property described above is also abstract, I cannot do this without
creating an instance of the mapper during registration. Five mappers?
No big deal. Four hundred mappers in a service layer? No way I want
to create an instance of all of those during registration. Not in an
environment where new domain objects and mappers can be added at
runtime, and their types registered.

And this is the thing: attributes? Come on. The issue here is to
force the mapper author to comply with the contract.

So--why not abstract statics?
Because they are messy, if you read everything posted there were a number of
arguments. The most important one is that there is no polymorphic way to
access static methods, you are forced to use reflection and any feature that
REQUIRES reflection to use it is not something that should exist, IMHO.
I would not ever use statics in that manner, attributes exist for just that
purpose(among others, of course). I do however think that a contract that
can handle required attributes should exist, that is a very different matter
entirely.
"Chris Capel" <[email protected]> wrote in message
 
Back
Top