Novice question about inherited constructors

O

Oleg Subachev

I am moving from Delphi to C# and hve encountered the problem:

I have the following classes and form Load event handler:

public class class1
{
public string S;
public class1( string aS )
{
S = aS;
}
}

public class class2 : class1
{
}

private void Form1_Load(object sender, System.EventArgs e)
{
class2 C2 = new class2( "string" );
label1.Text = C2.S;
}

When I try to compile I get the following errors:

No overload for method 'class1' takes '0' arguments
No overload for method 'class2' takes '1' arguments

What does it mean ?
Why inherited constructors are not used (as in Delphi) ?

Oleg Subachev
 
P

Peter Rilling

That is just part of the design of .NET that constructors are not inherited.
If you have a non-default constructor in a base class, you must also define
that same constructor and then pass the value up to its base.

public class2(string aS) : base(aS){...}
 
J

Jon Skeet [C# MVP]

Oleg said:
I am moving from Delphi to C# and hve encountered the problem:

When I try to compile I get the following errors:

No overload for method 'class1' takes '0' arguments

This is because the compiler is creating a default constructor for
class2, which tries to call a parameterless constructor in class1 - but
there isn't one.
No overload for method 'class2' takes '1' arguments

This is because there isn't a constructor in class2 taking a string,
because constructors aren't inherited.
Why inherited constructors are not used (as in Delphi) ?

If constructors were inherited, then *all* classes would have to have a
parameterless constructor, as System.Object does. I don't know how
Delphi gets around it, but personally I'm glad constructors aren't
inherited - it's good to be able to mandate that any instance of a
certain class *must* go through one of the constructors I've specified,
even if extra constructors have been added to the base class.

I view instance creation as somewhat different to instance use - things
which can be treated the same way after they've been created often have
very different creation requirements.

(Having said that, I *would* like some way of specifying what
constructors *must* be present in any type implementing a specific
interface, and possibly likewise for static methods. Extra syntax would
be necessary in order to call those constructors/static methods,
however - it does all get a bit complicated.)

Jon
 
T

the.duckman

Hey Jon,

I think that Idea causes some problems with the concept of an
interface. But I would like to a concept similar to an interface called
a "performa", the performa being what you described above. I feel some
tasks just don't relate to an interface and need something similar to
friend classes or something.

A classic example would be ISerializable. The concept of the interface
is not enought to encapuslate deserialisation (which requires a special
constructor).

It would be nice if the constructor often found when using
ISerializable was enforced. As such the serilaisation/deserialsation
requires a concept stronger than an interface.

So basicly Im with you, we need a way to enforce constructors....

I do however recall an article "somewhere" that explains why this is
"might" not possible under the CLR.

-dm
 
J

Joanna Carter [TeamB]

<[email protected]> a écrit dans le message de (e-mail address removed)...

| It would be nice if the constructor often found when using
| ISerializable was enforced. As such the serilaisation/deserialsation
| requires a concept stronger than an interface.

How about a constraint like with generics ?

public interface ISerializable requires new()
{

}

....or perhaps a special method syntax, like the property declaration :

public interface ISerializable
{
.ctor();
}

What think you ???

Joanna
 
J

Jon Skeet [C# MVP]

Joanna said:
| It would be nice if the constructor often found when using
| ISerializable was enforced. As such the serilaisation/deserialsation
| requires a concept stronger than an interface.

How about a constraint like with generics ?

That would be fine, except the only constraint available is that
there's a public parameterless constructor. It would often be nice to
be able to specify constructors with parameters, and this ability
doesn't exist with generics.

In addition, serialization itself recommends using a protected or
private constructor, which quite reasonably can't be expressed as a
constraint. Serialization is a pretty specialised area - I wouldn't
want to bend the platform too much to aid it. However, various things
which are dynamically loaded would benefit from enforcing some way of
constructing an instance (whether by a factory method or a
constructor).

Jon
 
D

David

How is
public class A
{
public A(){}
}
different from
public class B : A
{
public B() : base()
{}
}
 
J

Jon Skeet [C# MVP]

David said:
How is
public class A
{
public A(){}
}
different from
public class B : A
{
public B() : base()
{}
}

The first declares a type which derives from System.Object
(implicitly). The second declares a type which derives from A. Both
declare a public parameterless constructor which calls (implicitly in
the first case) the parameterless constructor in the base class.
 
D

David

Thank you. I am actually trying to figure out why a TreeView works when
nodes are constructed using the TreeNode class but do not work when using a
class derived from TreeNode.

What is the difference between

public class TreeNode
{
public TreeNode()
{
}

}

and

public class B : TreeNode
{
public B : base()
{}

}

?

Why does an index go out of range in LoadViewState with the later.
 
J

Jon Skeet [C# MVP]

David said:
Thank you. I am actually trying to figure out why a TreeView works when
nodes are constructed using the TreeNode class but do not work when using a
class derived from TreeNode.

What is the difference between

public class TreeNode
{
public TreeNode()
{
}

}

and

public class B : TreeNode
{
public B : base()
{}

}

?

Not a lot.
Why does an index go out of range in LoadViewState with the later.

I'm afraid I don't know.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
D

David

Here is the offending code.
//
// Contents of ValueNode.cs
//

using System;

using Microsoft.Web.UI.WebControls;

namespace TreeNodeProblem
{
/// <summary>
/// Summary description for ValueNode.
/// </summary>
public class ValueNode : TreeNode
{
public ValueNode() : base()
{
Text = "value";
}
}
}


//
// Contents of XNode.cs
//
using System;
using Microsoft.Web.UI.WebControls;

namespace TreeNodeProblem
{
/// <summary>
/// Summary description for XNode.
/// </summary>
public class XNode : TreeNode
{
public XNode() :base()
{
}
public XNode(string XStr) :base()
{
Text = XStr;
if(XStr == "Works")
{
TreeNode n = new TreeNode();
n.Text = "value";
Nodes.Add(n);
}
else
{
// ValueNode sets the Text property to "value"
ValueNode n = new ValueNode();
Nodes.Add(n);
}
}
}
}

//
// Contents of WebForm1.aspx.cs
//

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
//
//
// Added Line:
using Microsoft.Web.UI.WebControls;

namespace TreeNodeProblem
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected Microsoft.Web.UI.WebControls.TreeView tv;

private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
tv.AutoPostBack = true;
//
tv.Nodes.Add(new XNode("Works"));
//tv.Nodes.Add(new XNode("DoesNotWork"));

}
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
}
}


The WebForm1.aspx file HTML

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="TreeNodeProblem.WebForm1" %>
<%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls"
Assembly="Microsoft.Web.UI.WebControls" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<iewc:TreeView id="tv" style="Z-INDEX: 101; LEFT: 288px; POSITION:
absolute; TOP: 200px" runat="server"></iewc:TreeView>
</form>
</body>
</HTML>
 
J

Jon Skeet [C# MVP]

David said:
Here is the offending code.

<snip>

Thanks - I'll have a look as soon as I can. I'm not an ASP.NET expert
by any means, so it may take me a little longer to reproduce it that it
would with a console app, but I'll get onto it.
 
J

Jon Skeet [C# MVP]

David said:
Here is the offending code.

<snip>

Where does Microsoft.Web.UI.WebControls come from? I can find TreeView
and TreeNode in System.Web.UI.WebControls in v2, but not in 1.1, and I
can't see Microsoft.Web.UI.WebControls at all. Which version of VS.NET
are you using?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Wrong overload resolution ? 13
C# example 4
unable to access classs in VS2005 3
Overloaded Constructors 4
Process question? 2
Problems with Reflection 4
ControlCollection constructor 1
Problems with Delegates 7

Top