C# language feature proposal

  • Thread starter Thread starter Merlin
  • Start date Start date
M

Merlin

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.
 
Merlin said:
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 :)
 
Although I have seen explanations for not allowing this, I agree both would
be a good addition to the language.

[]'s,
Harkos
 
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.

Statics is another issue.

And constants.

And type declarations.

Regards,

Jasper Kent.
Harkos said:
Although I have seen explanations for not allowing this, I agree both would
be a good addition to the language.

[]'s,
Harkos
 
Jasper Kent 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.
Harkos said:
Although I have seen explanations for not allowing this, I agree both would
be a good addition to the language.

[]'s,
Harkos

Jon Skeet said:
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 :)
 
Jasper Kent 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.

Statics is another issue.

Not the way I'd considered it: these wouldn't be static methods with
implementations, they would be "abstract static" methods - very similar
to constructors. Basically it would ensure that implementors had the
appropriate constructors/static methods so that they could be called by
reflection. You'd still lose compile-time safety in the calling, but at
least implementors could get a compile-time error if they forgot to
implement the appropriate method/constructor. So yes, they *would*
offer a benefit.
And constants.

I don't see why they should go in interfaces particularly.
And type declarations.

Nor those.
 
presumably statics and constructors in interfaces would be non-CLS
compliant, so these would have to be ignored by languages that don't
understand them. Explicit implementation would also be illegal?

Still fail to see any real benefit; it doesn't enhance "interface based
programming". It doesn't as far as I understand make a difference to any
actual code. If it's mainly used for instantiation, for plugins etc, you
won't get far if instantiation fails; I guess the application can't even
assume the plugin class even implements the required i/f. Is there an
enlightening example anywhere?
 
Richard Cook said:
presumably statics and constructors in interfaces would be non-CLS
compliant, so these would have to be ignored by languages that don't
understand them.

Mmm... that would be a pain.
Explicit implementation would also be illegal?

Still fail to see any real benefit; it doesn't enhance "interface based
programming". It doesn't as far as I understand make a difference to any
actual code. If it's mainly used for instantiation, for plugins etc, you
won't get far if instantiation fails; I guess the application can't even
assume the plugin class even implements the required i/f. Is there an
enlightening example anywhere?

It doesn't change the actual plug-in code at all, no - what it *does*
mean is that the plug-in developer would get a compile-time error if
they got things wrong. That's all it would give, but maybe that's
enough.

As Nick Paldino has said, it's a shame there's not a good way to do the
other half of the problem - but with your first point here, that would
be a pain too...
 
I see what you mean about requiring statics to be defined in derived classes
so that they can be called by reflection. Sounds to me the sort of thing
that one would do in C++ with templates - and you'd get compile time
checking too. Maybe Generics will give us this.

Jasper Kent
 
Jasper Kent said:
I see what you mean about requiring statics to be defined in derived classes
so that they can be called by reflection. Sounds to me the sort of thing
that one would do in C++ with templates - and you'd get compile time
checking too. Maybe Generics will give us this.

I can't see how generics will help in this regard, to be honest.
 
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:
Jasper Kent 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 :)
 
I see your points on declaring types in interfaces (or classes). It's
certainly not a show-stopper to declare them in an associated namespace.

On the other hand, the absence of 'friend' in C# will increase the need to
nest classes for encapsulation reasons.

Jasper Kent.


Daniel O'Connell said:
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 :)
 
True enough, but:

1) As discussed elsewhere, this shouldn't really be declared as part of the
interface, because the constructor isn't called through virtual lookup. This
sort of thing (constructors and statics) could be enforced by some sore of
class requirements definition, but it would be a different thing from an
interface.

2) This particular feature of serialization in C# is not, IMHO, the greatest
bit of design. It seems to be somewhat overreliant on reflection. It would
seem more sensible to have an abstract Deserialize
(SerializationInfo,StreamingContext) and just construct with the default
constructor. Even that, however, requires that there is a default
constructor, which could only be determined at runtime. At least a default
constructor is more likely to exist than the serialization overload.

Oh how I miss C++ templates.

Jasper Kent.
 
Oh how I miss C++ templates.

I agree! Anyone know the latest on when we can expect a .Net release that
includes generics?

Josh
 
Jasper Kent said:
True enough, but:

1) As discussed elsewhere, this shouldn't really be declared as part of the
interface, because the constructor isn't called through virtual lookup. This
sort of thing (constructors and statics) could be enforced by some sore of
class requirements definition, but it would be a different thing from an
interface.

I generally agree. However, this is fairly close to the spirit of what an
interface is for, and it wouldn't disturb me too much to see it used for
"constructor interfaces," if it would help to solve this problem.

There are a number of similar features that could be handled at compile time
but aren't. For example, the requirement that ProxyAttribute only be
applied to classes inheriting from ContextBoundObject. I agree that this
wouldn't fit in with the idea of an interface, so maybe we do need some
alternative mechanism.
2) This particular feature of serialization in C# is not, IMHO, the greatest
bit of design. It seems to be somewhat overreliant on reflection. It would
seem more sensible to have an abstract Deserialize
(SerializationInfo,StreamingContext) and just construct with the default
constructor. Even that, however, requires that there is a default
constructor, which could only be determined at runtime. At least a default
constructor is more likely to exist than the serialization overload.

I agree that this is not the greatest design, although I'm not sure of the
alternatives, since they do need this to happen inside a constructor (or
something called by a constructor). Using the default constructor wouldn't
be a good solution since default constructors are very commonly used for
other things.

Wayne
 
A factory is (can be) an instance too though, so it can implement an
interface or extend an abstract class and maintain information about all the
instances it creates, if it is implemented as a singleton. Thus you can
separate out the way instances are created and their implementation to some
extent.

Potentially the only reflection part that is not compile-time checked is a
default constructor or static create method for the factory.

ie

WidgetFactory wf = WidgetFactory.Locate("MyWidgetFactory");

wf.SetLog(CurrentLog); // set properties or perform some operation on the
factory rather than the instances.

IWidget widget = wf.Create("Hello", false); // protected abstract IWidget
Create(string, bool) specified in WidgetFactory
widget.Text = "Zip";

here WidgetFactory could be an abstract class so able to track all the
WidgetFactory subclasses (plugins) it has loaded, and each WidgetFactory
subclass can track each IWidget implementation it creates.

I know this doesn't address everything, just thought i'd mention it i think
it can reduce use of reflection in some cases.
 
Back
Top