Jasper Kent said:
The term 'abstract constructor' is a bit like 'clockwork orange'. It's easy
enough to stick the two words together, but that doesn't mean you've created
a coherent concept.
Its simply a selection of words. The goal is basically to require an
interface implementer to have to implement a given constructor. It would be
an enhancement to loosely knitted modular or plugin designs.
Although i can't think of one off hand, there are a couple interfaces in the
framework that are expected to have a given constructor. There is no way to
enforce it at compile-time, the interface class would simply not launch
properly.
I however don't agree with placing constructor, static method, or any other
kind of requirements in an interface, as I feel that *most* code that uses
the interface has no interest in the constructors, static methods, etc
required to create and\or manage the interfaces implementing type.
On the other hand, I clearly see the point in having a method of declaring a
set of interfaces, attributes, constructors, and base class a given type
must implement (not inherit, note the difference). Every project I do
involves more and more reflection. Most work I do now uses interfaces to
bind things together leaving the actual implementation hidden, often times
allowing for the specific implementation to be defined in a config file. And
for each project I end up writing atleast one loader class, each class being
pretty un-reusable because of because of the intricacies involved in the
construction of each different type. A generic loader class could be
designed, but I suspect that eventually I'd find problems that wouldn't work
and have to change my generic class, hopefully not breaking any other client
using it, or if i covered all bases it would likely require almost as much
work as the equivilent reflection code.
After thinking all those things through, I keep coming back to the same
idea. Namely an additional, for lack of a better term, base type(ie class,
interface, struct) that specifies class requirements. Something that can say
this class must implement interface A, B, and C. That there must be a
constructor with the signature (string name), that attribute X must be
defined on the class, that attribute Y should not be defined, that attribute
Z must be defined on method Bar, or that static method void Foo(int x)
should exist on the implementing type. The type would work something like an
interface, instead of providing implementation or providing and interface
into that implementation, it would instead provide a package of requirements
the system needs to create the implementing instance.
Much of this can be solved with an abstract class, however there are
problems with that. They cannot define required attributes, static methods
and constructors don't inherit nor can they be abstract(as you pointed out),
target classes couldn't derive from classes they may need to(assuming no
base class is specified, of course), modules couldn't provide two sets of
requirements, as one base class would provide one set of requirements, plus
other various minor issues.
It could also be argued that introducing a new base type makes no sense and
interface should simply be beefed up to support whats needed. However, like
I mentioned above, most code that uses interfaces doesn't actually care
about how it was created, what needs to be done to safely unload it, or
anything of that matter, that is the responsibility of the loading system.
Providing that level of information to a client is unnessecery.
Of course, adding a new base type would add quite a bit of complexity to the
language and I'm sure it would cause a number of problems I've not even
begun to think up. It is still the only way i've been able to think of that
provides compile time and runtime verification, and if the compiler was
written properly, could help developers avoid a considerable amount of
reflection code.
Ahh well, just my 5am musings. (btw, there is another comment further down,
By statics, I didn't mean abstracts statics (because they are clockwork
oranges too) but static data and methods in the interface. Structurally it
would be a matter of style whether these go in an interface or a separate
helper class, but the point is they don't detract from an interface
being
an
interface. They fact they are in the interface is just a scoping issue.
As
I
said, it's a separate issue, though personally, I wouldn't allow them in
interfaces.
Java does allow constants in interfaces. Again, like statics, they don't
hurt. However, I guess the reason that Java allows constants is that it
doesn't have enums (Boo! Hiss!), and the fact that enums (and all type
declarations) are not allowed in interfaces in C# is the real problem.
In C# we might define a method in an interface which returns (or takes
as
a
parameter) and enum. For examples IChessBoard.ValidateMove (...) could
return an enum of {GOOD,ILLEGAL,CHECK,CHECKMATE}. The return type is
part
of
the interface so it would be nice if it could be declared in there. The same
goes for other type declarations (i.e. classes and structs).
IChessBoard.GetPieceAt (...) needs to returns a pair of piece type and
colour (either as a struct or a class). This is best defined in the
IChessBoard interface. Type declarations (for which no instances are
declared) carry no data and hence don't break any of the rules of
interfaces.
In this case, an associated enum is just as easy, as you imply. However I
take issue with most enums and classes declared within the scope of another
type, I seem to find issues where the contained class\enum is useful
somewhere else but the containing class makes it feel very absurdly placed.
I personally only think a class should be internal to another when there is
good reason to, perhaps because they interact in some manner inappropriate
or impossible in other situations, not simply because they make sense
together.
I also don't think an enum should ever be within the scope of another type.
Really it's all just a scoping issue. The question is (and there's probably
a good answer) why can't an interface be used to define it's own namespace?
Obviously all these are MSIL issues, not pure C# issues.
Regards,
Jasper Kent.
Daniel O'Connell said:
What is the point of having constructors on interfaces? They can't have
data, so what is there to construct? You may mean abstract constructors,
but
it would offer no benefit, since they could never be accessed though the
interface reference, only through the implementation class.
Abstract constructors is the idea, basically an attempt to define a method
to require a given class to have a given constructor (needed for some
patterns). I don't think this is something appropriate for an interface,
myself.
Statics is another issue.
Explicit statics defined on the interface have no point, just stick
them
in
a class. Defining that a class requires the existance of a static has its
uses, but again isn't something an interface should do.
And constants.
Why define a constant on an interface...thats what classes are for as well.
If you want it associated with a specific interface, then a related class
makes more sense than adding such things directly to the interface.
And type declarations.
What do you mean?
Regards,
Jasper Kent.
Although I have seen explanations for not allowing this, I agree both
would
be a good addition to the language.
[]'s,
Harkos
"Jon Skeet" <
[email protected]> escreveu na mensagem
I believe that interfaces are one of the more useful
design constructs available in C#. However, there's one
thing that I feel is missing in them. I propose that
interfaces be expanded to allow the specification of
constructors. Admittedly, this makes things a bit
confusing in that seeing constructors in an interface
seems to imply that the interface itself can be
instantiated. But I don't believe that it would be
significantly worse than the similar situation with
methods. Often enough, a family of classes will be
derived from an interface that are designed to have the
same basic set of constructors.
And likewise static methods. It's been discussed before