Force Implementation of a Constructor

  • Thread starter Thread starter Steve - DND
  • Start date Start date
S

Steve - DND

I know it's possible to require inheriting classes to implement a particular
function or property, but is it possible to require a inheriting class to
implement a constructor of it's own?

Thanks,
Steve
 
Steve - DND said:
I know it's possible to require inheriting classes to implement a particular
function or property, but is it possible to require a inheriting class to
implement a constructor of it's own?

No, I'm afraid not.
 
Hi Steve,
No, there is no way?
Unless if you declare only protected constructors for the base class.

class Foo
{
protected Foo()
{
}
}

Now if I want to inherit from this class and be able to instatiate objects I
have to declare at least one public constructor. But I cannot force the
inheritors to declare constructor with specific prototype (as I can do with
abstract methods).

class Bar: Foo
{
public Bar()
{
}
}

What do you need that for? I can't think of any useful application of this.

HTH
B\rgds
100
 
What do you need that for? I can't think of any useful application of this.

I can, very easily: plug-in systems. Basically, sooner or later in any
plug-in framework you need to instantiate a type which you don't know
about at compile-time. You'll have to instantiate it with reflection
anyway, but it would help if the plug-in author got an error when
writing the type if they didn't provide an appropriate constructor.
 
Jon Skeet said:
this.
I can, very easily: plug-in systems. Basically, sooner or later in any
plug-in framework you need to instantiate a type which you don't know
about at compile-time. You'll have to instantiate it with reflection
anyway, but it would help if the plug-in author got an error when
writing the type if they didn't provide an appropriate constructor.

Wouldn't you use an interface to define the plugin, then why would you care
about the constructor? What I mean is the functionality of a Foo
constructor Foo(int a, int b); Could simply be Init(int a, int b) in an
interface, ignoring a constructor completely.

-- Alan
 
You could do this with generics.

But if you need a definatie API, use an interface, or if you need a definate
behaviour, use abstract base classes
 
news.microsoft.com said:
But if you need a definatie API, use an interface, or if you need a definate
behaviour, use abstract base classes

In this case you could do both. Inherit functionality from PluginBase() and
yet implement IPlugin.

-- Alan
 
Alan Pretre said:
Wouldn't you use an interface to define the plugin, then why would you care
about the constructor?

To create an instance of the type that implements the interface.
What I mean is the functionality of a Foo
constructor Foo(int a, int b); Could simply be Init(int a, int b) in an
interface, ignoring a constructor completely.

How do you call Init in the first place? If it's a static method, you
can't specify that in the interface, and if it's an instance method
then you're back to the question of how you create an instance in the
first place.
 
Jon Skeet said:
To create an instance of the type that implements the interface.

By definition, it would be of the type if it implemented the interface.
How do you call Init in the first place? If it's a static method, you
can't specify that in the interface, and if it's an instance method
then you're back to the question of how you create an instance in the
first place.

I mean created with a default constructor then refined based on appropriate
instance methods or overloads or whatever.

-- Alan
 
Alan Pretre said:
By definition, it would be of the type if it implemented the interface.

Yes - but you'd need to create an instance of it in order to use it
though, is my point.
I mean created with a default constructor then refined based on appropriate
instance methods or overloads or whatever.

That relies on there *being* a parameterless constructor though - and
you can't enforce that. (It would also restrict the plugin to being a
mutable type, which isn't ideal.)
 
Jon Skeet said:
Yes - but you'd need to create an instance of it in order to use it
though, is my point.

Hmmm... Is it not the case that the a default constructor will be defined
for you if you don't put one in yourself?

I know that C++ will do that for you, UNLESS you have defined other
constructors that take parameters, in which case if a class is used in a
context that requires a default constructor this would cause a compilation
error.

I don't know the rule for C#...

-- Alan
 
Alan Pretre said:
Hmmm... Is it not the case that the a default constructor will be defined
for you if you don't put one in yourself?

If you don't put in *any* constructor, a default one will be provided,
yes. (When most people say "default constructor" they really mean a
parameterless constructor.)
I know that C++ will do that for you, UNLESS you have defined other
constructors that take parameters, in which case if a class is used in a
context that requires a default constructor this would cause a compilation
error.

I don't know the rule for C#...

It's the same. Except that you won't get to know it at compile time
with a plug-in, because the compiler (for the framework) won't know
whether or not there's a constructor, and you won't be calling it
directly anyway, you'll be using reflection. The compiler for the
plugin won't complain either because there's no way of expressing in
the interface that concrete types implementing the interface should
have a parameterless constructor.
 
System.Object defines a default ctor.



Alan Pretre said:
Hmmm... Is it not the case that the a default constructor will be defined
for you if you don't put one in yourself?

I know that C++ will do that for you, UNLESS you have defined other
constructors that take parameters, in which case if a class is used in a
context that requires a default constructor this would cause a compilation
error.

I don't know the rule for C#...

-- Alan
 
Alan (& Jon),
A very good example of an Interface that 'requires' you implement a specific
constructor is the ISerializable interface, if you define a class that
implements the ISerializable interface, it is understood that you also need
to implement a constructor that accepts SerializationInfo & StreamingContext
parameters.

What Jon is trying to say, there is no way for the ISerializable interface
to specify that it "requires" you to implement the constructor, however if
you do not implement the constructor, then at run time you will receive a
runtime error! Where as if there was a way for the interface to specify a
constructor, then you would receive a compile error... Compile errors are
always better then runtime errors in my book!

The following article explains the rational to having the interface
"require" a constructor, over a "SetObjectData" method.

http://msdn.microsoft.com/msdnmag/issues/02/07/net/

Hope this helps
Jay
 
Jay B. Harlow said:
A very good example of an Interface that 'requires' you implement a specific
constructor is the ISerializable interface, if you define a class that
implements the ISerializable interface, it is understood that you also need
to implement a constructor that accepts SerializationInfo & StreamingContext
parameters.

What Jon is trying to say, there is no way for the ISerializable interface
to specify that it "requires" you to implement the constructor, however if
you do not implement the constructor, then at run time you will receive a
runtime error! Where as if there was a way for the interface to specify a
constructor, then you would receive a compile error... Compile errors are
always better then runtime errors in my book!

Hi, Jay. Here is the relevant quote from the ISerializable doc:

http://msdn.microsoft.com/library/d...ntimeserializationiserializableclasstopic.asp

"The ISerializable interface implies a constructor with the signature
Constructor(SerializationInfo info, StreamingContext context). At
deserialization time, the current constructor is called only after the data
in the SerializationInfo has been deserialized by the formatter."

The ISerializable interface only has one member, GetObjectData():

http://msdn.microsoft.com/library/d...imeserializationiserializablememberstopic.asp

What I don't understand is why they chose to do it the way they did. If
they would have added another method to ISerializable, say
SetObjectData(SerializationInfo info, StreamingContext context), and not
required that specific constructor, only a default one, then it would have
achieved the goal that you stated (compile time detection).

I read that article you referenced and I'm not convinced that their method
has any advantages over this one. This perhaps puts a little more burden on
the class design, because it would have to reinitialize AFTER construction.
That's the only drawback that I can see.

-- Alan
 
Alan Pretre said:
What I don't understand is why they chose to do it the way they did. If
they would have added another method to ISerializable, say
SetObjectData(SerializationInfo info, StreamingContext context), and not
required that specific constructor, only a default one, then it would have
achieved the goal that you stated (compile time detection).

How? A class with a constructor which took a parameter would still
compile, but wouldn't have the required parameterless constructor.
 
Jon Skeet said:
How? A class with a constructor which took a parameter would still
compile, but wouldn't have the required parameterless constructor.

I'm with you now.

I tried this program and got the exception:

System.MissingMethodException: No parameterless constructor defined for this
object.


public class Foo {
private int _x;

public Foo(int x) {
_x = x;
}
}

public class App {
public static void Main() {
App A = new App();

System.Type FooType = A.GetType().Assembly.GetType("Foo");
Foo F = (Foo) System.Activator.CreateInstance(FooType);
return;
}
}


So we would be trading one constructor type for another; either way there is
a compiler-unenforced rule to provide a specific kind of constructor.

-- Alan
 
Alan,
I read that article you referenced and I'm not convinced that their method
has any advantages over this one. This perhaps puts a little more burden on
the class design, because it would have to reinitialize AFTER construction.
That's the only drawback that I can see.
I guess I need to ask: Do you see any value in defining readonly fields in
your classes?

Do you see any value in having the compiler enforce those readonly fields to
the class members themselves, as opposed to controlling the 'readonly'-ness
with a readonly property?

Do you see any value in having different instances having different values
for the readonly field.

Such a field may be Created, where the object has a date & time that it
entered a system, never to be changed during the lifetime (in memory or on
disk) of the object. Hence make the field itself immutable with the readonly
modifier. Which prevents the class itself from modifying the field. Yet
different instances of the class have different Created properties...

If you do, then you should see why defining ISerializable.SetObjectData
won't "cut it", and Serialization needs to use the constructor, as the
readonly field can only be initialized in the constructor.

If you don't see the value in immutable fields defined with readonly, then
yes I can see why you would think that ISerializable.SetObjectData is "good
enough".

Maybe its just that I like making immutable fields readonly, just for that
extra protection that the compiler won't let me modify the field...

Note although the above is blunt, it was not meant as a slam!

Hope this helps
Jay
 
Back
Top