Petzold Assumed I Could Figure It Out -- I Am Stumped

T

Tom

First, my thanks in advance to those who can help explain away this
mystery line of code.

Petzold is a great teacher and I appreciate his work; however, his
explanation about an extra line of code needed when a class is
contained in a library vs the class being defined in a separate file
within the project falls short of my ability to understand.

Note: I've included the code (4 files) at the bottom, making this a
long winded posting; however, to emphasize the slight variance between
a library file and an included file ... I felt compelled to include
the code in it's entirety.

Restating the above >> An event override within a locally defined
class does NOT require the base class method to be called; however,
when defining the SAME class within a DLL with the exact same
functionality ... you MUST call the base method.

protected override void OnClick(EventArgs args)
{
base.OnClick(args); // *** This is the extra line of code ***
MessageBox.Show(MessageBoxText, Text);
}

ref: "2005 Edition - Programming Microsoft Windows Forms - A
Streamlined Approach Using C#", by Charles Petzold, page #45.

In Petzold's words >> "I've also added a statement to the OnClick
method to call the same method in the base class (which is Button).
Without this statement, a program couldn't attach a Click event
handler for MessageButton."

My confusion raises many questions:

1) Why does a class defined in a library file require this extra line
of code? Is there a problem within the JIT compilers and this is
simply a "trick" to make using a DLL work? (I doubt it. Programming is
very precise. I am just confused!!)

2) How do you know when to call a base class method? If you are
overriding the method ... why must the base method be called? If the
base method "does something" that you want to avoid or change by
overriding it ... does it make sense to have to call it?

3) Is a library file not simply a block of code that is reusable and
essentially the same as being included within the project? (Let's
exclude data argument marshaling between unmanaged DLL's and managed
code. A valid complexity for sure ... but not the focal point.)

4) Is the "public" access of the library's MessageButton class a
contributing factor?

5) What types of rules of understanding can be applied so one knows
when to call the base method?

Note: I've compiled and ran both programs below. They are solid and
behave the same. Also, all of the examples and solution files for the
referenced text can be found at:

http://www.microsoft.com/mspress/companion/0-7356-2153-5/

The library file:

// The Library Contained MessageButton Class File: >>

//-------------------------------------------------
// MessageButtonLib.cs (c) 2005 by Charles Petzold
//-------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Petzold.ProgrammingWindowsForms
{
public class MessageButton: Button
{
string strMessageBoxText;

public MessageButton()
{
Enabled = false;
}
public string MessageBoxText
{
set
{
strMessageBoxText = value;
Enabled = value != null && value.Length > 0;
}
get
{
return strMessageBoxText;
}
}
protected override void OnClick(EventArgs args)
{
base.OnClick(args);
MessageBox.Show(MessageBoxText, Text);
}
}
}

// The File For Using the library file: >>

//----------------------------------------------------
// ProgramUsingLibrary.cs (c) 2005 by Charles Petzold
//----------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Petzold.ProgrammingWindowsForms;

class ProgramUsingLibrary: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new ProgramUsingLibrary());
}
public ProgramUsingLibrary()
{
Text = "Program Using Library";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;
}
}

==========================================================================
==========================================================================
==========================================================================

// The "Locally Defined MessageButton Class"
// Within A Separate File: >>

//----------------------------------------------
// MessageButton.cs (c) 2005 by Charles Petzold
//----------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

class MessageButton: Button
{
string strMessageBoxText;

public MessageButton()
{
Enabled = false;
}
public string MessageBoxText
{
set
{
strMessageBoxText = value;
Enabled = value != null && value.Length > 0;
}
get
{
return strMessageBoxText;
}
}
protected override void OnClick(EventArgs args)
{
MessageBox.Show(MessageBoxText, Text);
}
}


// File For Using the MessageButton Class: >>

//--------------------------------------------------
// MessageButtonDemo.cs (c) 2005 by Charles Petzold
//--------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

class MessageButtonDemo: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MessageButtonDemo());
}
public MessageButtonDemo()
{
Text = "MessageButton Demo";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;
}
}
 
L

Liz

First, my thanks in advance to those who can help explain away this
mystery line of code.

Petzold is a great teacher and I appreciate his work; however, his
explanation about an extra line of code needed when a class is
contained in a library vs the class being defined in a separate file
within the project falls short of my ability to understand.


Actually, Petzold doesn't say everything you're attributing to him; the
point he makes is simply stated: "I've also added a statement to the OnClick
method to call the same method in the base class (which is Button). Without
this statement, a program couldn't attach a Click event handler for
MessageButton."

Far as I know, this is all correct and I don't know where he says that it's
ok to *not* call the base method "locally." It is indeed "ok" in either
case but there is a consequence which you may or may not care about in your
own code; but if you distribute your class in a DLL to someone else
expecting different behavior, it could be a problem, no?

It makes no difference whatsoever whether the code is in a library file or
an "included file"

Note: I've included the code (4 files) at the bottom, making this a
long winded posting; however, to emphasize the slight variance between
a library file and an included file ... I felt compelled to include
the code in it's entirety.

Restating the above >> An event override within a locally defined
class does NOT require the base class method to be called; however,
when defining the SAME class within a DLL with the exact same
functionality ... you MUST call the base method.

protected override void OnClick(EventArgs args)
{
base.OnClick(args); // *** This is the extra line of code ***
MessageBox.Show(MessageBoxText, Text);
}

ref: "2005 Edition - Programming Microsoft Windows Forms - A
Streamlined Approach Using C#", by Charles Petzold, page #45.

In Petzold's words >> "I've also added a statement to the OnClick
method to call the same method in the base class (which is Button).
Without this statement, a program couldn't attach a Click event
handler for MessageButton."

My confusion raises many questions:

1) Why does a class defined in a library file require this extra line
of code? Is there a problem within the JIT compilers and this is
simply a "trick" to make using a DLL work? (I doubt it. Programming is
very precise. I am just confused!!)

2) How do you know when to call a base class method? If you are
overriding the method ... why must the base method be called? If the
base method "does something" that you want to avoid or change by
overriding it ... does it make sense to have to call it?

3) Is a library file not simply a block of code that is reusable and
essentially the same as being included within the project? (Let's
exclude data argument marshaling between unmanaged DLL's and managed
code. A valid complexity for sure ... but not the focal point.)

4) Is the "public" access of the library's MessageButton class a
contributing factor?

5) What types of rules of understanding can be applied so one knows
when to call the base method?

Note: I've compiled and ran both programs below. They are solid and
behave the same. Also, all of the examples and solution files for the
referenced text can be found at:

http://www.microsoft.com/mspress/companion/0-7356-2153-5/

The library file:

// The Library Contained MessageButton Class File: >>

//-------------------------------------------------
// MessageButtonLib.cs (c) 2005 by Charles Petzold
//-------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Petzold.ProgrammingWindowsForms
{
public class MessageButton: Button
{
string strMessageBoxText;

public MessageButton()
{
Enabled = false;
}
public string MessageBoxText
{
set
{
strMessageBoxText = value;
Enabled = value != null && value.Length > 0;
}
get
{
return strMessageBoxText;
}
}
protected override void OnClick(EventArgs args)
{
base.OnClick(args);
MessageBox.Show(MessageBoxText, Text);
}
}
}

// The File For Using the library file: >>

//----------------------------------------------------
// ProgramUsingLibrary.cs (c) 2005 by Charles Petzold
//----------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Petzold.ProgrammingWindowsForms;

class ProgramUsingLibrary: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new ProgramUsingLibrary());
}
public ProgramUsingLibrary()
{
Text = "Program Using Library";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;
}
}

==========================================================================
==========================================================================
==========================================================================

// The "Locally Defined MessageButton Class"
// Within A Separate File: >>

//----------------------------------------------
// MessageButton.cs (c) 2005 by Charles Petzold
//----------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

class MessageButton: Button
{
string strMessageBoxText;

public MessageButton()
{
Enabled = false;
}
public string MessageBoxText
{
set
{
strMessageBoxText = value;
Enabled = value != null && value.Length > 0;
}
get
{
return strMessageBoxText;
}
}
protected override void OnClick(EventArgs args)
{
MessageBox.Show(MessageBoxText, Text);
}
}


// File For Using the MessageButton Class: >>

//--------------------------------------------------
// MessageButtonDemo.cs (c) 2005 by Charles Petzold
//--------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

class MessageButtonDemo: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MessageButtonDemo());
}
public MessageButtonDemo()
{
Text = "MessageButton Demo";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;
}
}
 
L

Liz

Tom said:
First, my thanks in advance to those who can help explain away this
mystery line of code.

Petzold is a great teacher and I appreciate his work; however, his
explanation about an extra line of code needed when a class is
contained in a library vs the class being defined in a separate file
within the project falls short of my ability to understand.

replace the ProgramUsingLibrary.cs file with the code below (which does
nothing more than subscribe to the Click event), then comment out the
statement:

base.OnClick(args);

in MessageButtonLib.cs

you should see the problem with not calling the base method.


//----------------------------------------------------
// ProgramUsingLibrary.cs (c) 2005 by Charles Petzold
//----------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Petzold.ProgrammingWindowsForms;

class ProgramUsingLibrary: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new ProgramUsingLibrary());
}
public ProgramUsingLibrary()
{
Text = "Program Using Library";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;

msgbtn.Click += new EventHandler(msgbtn_Click);
}

void msgbtn_Click(object sender, EventArgs e)
{
MessageBox.Show("click");
}


}


Note: I've included the code (4 files) at the bottom, making this a
long winded posting; however, to emphasize the slight variance between
a library file and an included file ... I felt compelled to include
the code in it's entirety.

Restating the above >> An event override within a locally defined
class does NOT require the base class method to be called; however,
when defining the SAME class within a DLL with the exact same
functionality ... you MUST call the base method.

protected override void OnClick(EventArgs args)
{
base.OnClick(args); // *** This is the extra line of code ***
MessageBox.Show(MessageBoxText, Text);
}

ref: "2005 Edition - Programming Microsoft Windows Forms - A
Streamlined Approach Using C#", by Charles Petzold, page #45.

In Petzold's words >> "I've also added a statement to the OnClick
method to call the same method in the base class (which is Button).
Without this statement, a program couldn't attach a Click event
handler for MessageButton."

My confusion raises many questions:

1) Why does a class defined in a library file require this extra line
of code? Is there a problem within the JIT compilers and this is
simply a "trick" to make using a DLL work? (I doubt it. Programming is
very precise. I am just confused!!)

2) How do you know when to call a base class method? If you are
overriding the method ... why must the base method be called? If the
base method "does something" that you want to avoid or change by
overriding it ... does it make sense to have to call it?

3) Is a library file not simply a block of code that is reusable and
essentially the same as being included within the project? (Let's
exclude data argument marshaling between unmanaged DLL's and managed
code. A valid complexity for sure ... but not the focal point.)

4) Is the "public" access of the library's MessageButton class a
contributing factor?

5) What types of rules of understanding can be applied so one knows
when to call the base method?

Note: I've compiled and ran both programs below. They are solid and
behave the same. Also, all of the examples and solution files for the
referenced text can be found at:

http://www.microsoft.com/mspress/companion/0-7356-2153-5/

The library file:

// The Library Contained MessageButton Class File: >>

//-------------------------------------------------
// MessageButtonLib.cs (c) 2005 by Charles Petzold
//-------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Petzold.ProgrammingWindowsForms
{
public class MessageButton: Button
{
string strMessageBoxText;

public MessageButton()
{
Enabled = false;
}
public string MessageBoxText
{
set
{
strMessageBoxText = value;
Enabled = value != null && value.Length > 0;
}
get
{
return strMessageBoxText;
}
}
protected override void OnClick(EventArgs args)
{
base.OnClick(args);
MessageBox.Show(MessageBoxText, Text);
}
}
}

// The File For Using the library file: >>

//----------------------------------------------------
// ProgramUsingLibrary.cs (c) 2005 by Charles Petzold
//----------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Petzold.ProgrammingWindowsForms;

class ProgramUsingLibrary: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new ProgramUsingLibrary());
}
public ProgramUsingLibrary()
{
Text = "Program Using Library";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;
}
}

==========================================================================
==========================================================================
==========================================================================

// The "Locally Defined MessageButton Class"
// Within A Separate File: >>

//----------------------------------------------
// MessageButton.cs (c) 2005 by Charles Petzold
//----------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

class MessageButton: Button
{
string strMessageBoxText;

public MessageButton()
{
Enabled = false;
}
public string MessageBoxText
{
set
{
strMessageBoxText = value;
Enabled = value != null && value.Length > 0;
}
get
{
return strMessageBoxText;
}
}
protected override void OnClick(EventArgs args)
{
MessageBox.Show(MessageBoxText, Text);
}
}


// File For Using the MessageButton Class: >>

//--------------------------------------------------
// MessageButtonDemo.cs (c) 2005 by Charles Petzold
//--------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

class MessageButtonDemo: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MessageButtonDemo());
}
public MessageButtonDemo()
{
Text = "MessageButton Demo";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;
}
}
 
T

Tom

Thanks Liz --

I did comment out the "mystery" line and I see no difference in
behavior. The reason I attribute Petzold for it to be OK "not" to call
the base method in the locally defined file >> that line of code is
not there. He goes out of his way to say that he has added it in the
DLL version and that without it there is a problem ... but I do not
see the resulting problems in the code behavior.

I notice in some of the other examples within the book that similar
calls to the base method are present in protected overrides.

To me it seems the inherited methods should be avoided and only the
overridden code be executed? It seems illogical to call a method who's
behavior is not desired? Perhaps if the override is simply "adding" to
the base method ... then you call the base and follow it with your
additional coding?

I remain confused ... but very much appreciate your comments.

The fact I see no behavior changes after commenting out that line
makes me wonder if the JIT compiler might have had a bug in it that
has now been fixed? Petzold does discuss on page xiii that the
examples were based on a specific pre-release version: August 2005
Community Technical Review.

I'm trying to scrutinize Petzold's work and understand it fully. He
does leap at times and thus forces this student to dig a bit to
understand the examples. Painful, but in the long run the journey also
reveals additional tidbits. It is just this particular line of code
and the "reasoning" behind it has me stumped.

Thanks again.

-- Tom



Tom said:
First, my thanks in advance to those who can help explain away this
mystery line of code.

Petzold is a great teacher and I appreciate his work; however, his
explanation about an extra line of code needed when a class is
contained in a library vs the class being defined in a separate file
within the project falls short of my ability to understand.

replace the ProgramUsingLibrary.cs file with the code below (which does
nothing more than subscribe to the Click event), then comment out the
statement:

base.OnClick(args);

in MessageButtonLib.cs

you should see the problem with not calling the base method.


//----------------------------------------------------
// ProgramUsingLibrary.cs (c) 2005 by Charles Petzold
//----------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Petzold.ProgrammingWindowsForms;

class ProgramUsingLibrary: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new ProgramUsingLibrary());
}
public ProgramUsingLibrary()
{
Text = "Program Using Library";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;

msgbtn.Click += new EventHandler(msgbtn_Click);
}

void msgbtn_Click(object sender, EventArgs e)
{
MessageBox.Show("click");
}


}


Note: I've included the code (4 files) at the bottom, making this a
long winded posting; however, to emphasize the slight variance between
a library file and an included file ... I felt compelled to include
the code in it's entirety.

Restating the above >> An event override within a locally defined
class does NOT require the base class method to be called; however,
when defining the SAME class within a DLL with the exact same
functionality ... you MUST call the base method.

protected override void OnClick(EventArgs args)
{
base.OnClick(args); // *** This is the extra line of code ***
MessageBox.Show(MessageBoxText, Text);
}

ref: "2005 Edition - Programming Microsoft Windows Forms - A
Streamlined Approach Using C#", by Charles Petzold, page #45.

In Petzold's words >> "I've also added a statement to the OnClick
method to call the same method in the base class (which is Button).
Without this statement, a program couldn't attach a Click event
handler for MessageButton."

My confusion raises many questions:

1) Why does a class defined in a library file require this extra line
of code? Is there a problem within the JIT compilers and this is
simply a "trick" to make using a DLL work? (I doubt it. Programming is
very precise. I am just confused!!)

2) How do you know when to call a base class method? If you are
overriding the method ... why must the base method be called? If the
base method "does something" that you want to avoid or change by
overriding it ... does it make sense to have to call it?

3) Is a library file not simply a block of code that is reusable and
essentially the same as being included within the project? (Let's
exclude data argument marshaling between unmanaged DLL's and managed
code. A valid complexity for sure ... but not the focal point.)

4) Is the "public" access of the library's MessageButton class a
contributing factor?

5) What types of rules of understanding can be applied so one knows
when to call the base method?

Note: I've compiled and ran both programs below. They are solid and
behave the same. Also, all of the examples and solution files for the
referenced text can be found at:

http://www.microsoft.com/mspress/companion/0-7356-2153-5/

The library file:

// The Library Contained MessageButton Class File: >>

//-------------------------------------------------
// MessageButtonLib.cs (c) 2005 by Charles Petzold
//-------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Petzold.ProgrammingWindowsForms
{
public class MessageButton: Button
{
string strMessageBoxText;

public MessageButton()
{
Enabled = false;
}
public string MessageBoxText
{
set
{
strMessageBoxText = value;
Enabled = value != null && value.Length > 0;
}
get
{
return strMessageBoxText;
}
}
protected override void OnClick(EventArgs args)
{
base.OnClick(args);
MessageBox.Show(MessageBoxText, Text);
}
}
}

// The File For Using the library file: >>

//----------------------------------------------------
// ProgramUsingLibrary.cs (c) 2005 by Charles Petzold
//----------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Petzold.ProgrammingWindowsForms;

class ProgramUsingLibrary: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new ProgramUsingLibrary());
}
public ProgramUsingLibrary()
{
Text = "Program Using Library";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;
}
}

==========================================================================
==========================================================================
==========================================================================

// The "Locally Defined MessageButton Class"
// Within A Separate File: >>

//----------------------------------------------
// MessageButton.cs (c) 2005 by Charles Petzold
//----------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

class MessageButton: Button
{
string strMessageBoxText;

public MessageButton()
{
Enabled = false;
}
public string MessageBoxText
{
set
{
strMessageBoxText = value;
Enabled = value != null && value.Length > 0;
}
get
{
return strMessageBoxText;
}
}
protected override void OnClick(EventArgs args)
{
MessageBox.Show(MessageBoxText, Text);
}
}


// File For Using the MessageButton Class: >>

//--------------------------------------------------
// MessageButtonDemo.cs (c) 2005 by Charles Petzold
//--------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

class MessageButtonDemo: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MessageButtonDemo());
}
public MessageButtonDemo()
{
Text = "MessageButton Demo";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;
}
}
 
L

Liz

Tom said:
Thanks Liz --

I did comment out the "mystery" line and I see no difference in
behavior.

of course there is, Tom ... as Petzold points out, without the base method
call, you cannot attach a Click event handler (well, you can, but it won't
function) .... that should be clear from commenting/uncommenting the
base.OnClick(args) statement and running the code.
The reason I attribute Petzold for it to be OK "not" to call
the base method in the locally defined file >> that line of code is
not there. He goes out of his way to say that he has added it in the
DLL version and that without it there is a problem ... but I do not
see the resulting problems in the code behavior.

I'm not sure I'd characterize it as "going out of his way" nor do I think
he's differentiating DLLs on this point; the inclusion of the call in the
DLL seems to more incidental than otherwise ... the section is a brief
description/tutorial on creating DLLs; note that he points out that it is
"courteous" to use a namespace in your DLL and essential to declare classes
as public; now he does not say that you *must* call the base method; he
merely points out the effect of not doing so: if you want the user of your
DLL to able to make the full and best use of it, you call the base method.
I don't consider this to be gospel; it's just good general counsel which
can be ignored where appropriate.
To me it seems the inherited methods should be avoided and only the
overridden code be executed? It seems illogical to call a method who's
behavior is not desired? Perhaps if the override is simply "adding" to
the base method ... then you call the base and follow it with your
additional coding?

I understand you on this one and I think the answer is "it depends" on the
code you're writing and the way you intend/expect it to be used; I think it
might have been useful to have some examples from the maestro illustrating
when/why you want to call base methods and when/why you might not want to.
Surely you've noticed this is a relatively short book ... much is left
unsaid and left to the reader to ponder and figure out .. the approach has
its pros and cons but all overall I think it's useful and well-written.
I remain confused ... but very much appreciate your comments.

why don't you drop Charles an email and see if he has any comment on the
matter?
 
T

Tom

Liz --

I agree with you fully on the "maestro" tag. I don't feel qualified to
approach Petzold directly out of respect for his time and respect for
his invaluable works.

The forms book is condensed and I like it that way. I am among those
who got lost in the verbose coverage of graphics in other books. A
little struggle and challenge is needed to engage the learning process
and I am finding the forms book to be a good balance for me.

Petzold explains the extra overhead that VS generates very well and
when namespaces and the extra solution layer are not really needed for
the tiny learning programs. I am a big fan of concise code. There are
few callings higher than teaching ... the writing challenge to be
technically perfect, concise, thorough, and remain readable is way out
of my grasp.

I have been and remain a fan of Petzold's published works.

Just in this specific case ... the need for the base class method call
escapes me. I want to understand the logic fully. There is a reason
for the base method inclusion. That reason may not be required in this
case; however, if I can understand when to use it properly ... I will
have benefitted more so than simply moving on.

To add to my confusion is another program within the same book:
Chapter 3, ColorFill.

There, you can find a similar base method call in the following:

protected override void OnFontChanged(EventArgs args)
{
base.OnFontChanged(args); // << similar base method call ?????
Padding = new Padding(Padding.Left, yDpi / 10 + Font.Height,
Padding.Right, Padding.Bottom);
}

Again, I run the program with and without the base method call and on
my system the resulting behavior is the same. Compiles correctly and
runs identically.

Thus I remain convinced there are times when you should call the base
method and I would like to understand the logic to this level and
beyond someday. For these specific cases (and others within the same
book) ... what purpose is served calling the base method?

-- Tom
 
L

Liz

Tom said:

I'm not sure where we're not communicating here; below is the program that
needs to be modified to see the difference in behavior; I'm clearly marking
the lines of code I added to expose the difference ... perhaps you didn't
add them to your code? If you comment out the statement base.OnClick(args)
you will not get execution of the code in the method "msgbtn_Click" ... if
you un-comment the statement base.OnClick(args) you WILL get execution of
the method "msgbtn_Click"

//----------------------------------------------------
// ProgramUsingLibrary.cs (c) 2005 by Charles Petzold
//----------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Petzold.ProgrammingWindowsForms;

class ProgramUsingLibrary: Form
{
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new ProgramUsingLibrary());
}
public ProgramUsingLibrary()
{
Text = "Program Using Library";

MessageButton msgbtn = new MessageButton();
msgbtn.Parent = this;
msgbtn.Text = "Calculate 10,000,000 digits of PI";
msgbtn.MessageBoxText = "This button is not yet implemented!";
msgbtn.Location = new Point(50, 50);
msgbtn.AutoSize = true;

msgbtn.Click += new EventHandler(msgbtn_Click); // *** ADDED THIS
LINE
}

void msgbtn_Click(object sender, EventArgs e) // *** ADDED THIS
LINE
{ // *** ADDED THIS
LINE
MessageBox.Show("click"); // *** ADDED THIS
LINE
} // *** ADDED THIS
LINE
}
Just in this specific case ... the need for the base class method call
escapes me. I want to understand the logic fully. There is a reason
for the base method inclusion. That reason may not be required in this
case; however, if I can understand when to use it properly ... I will
have benefitted more so than simply moving on.

let's consider a (silly) example: you're designing a UI control -- a
button -- which when clicked will call a block of code which will dispatch a
"send in the troops" message to the Joint Chiefs of Staff by email. Your
control will be used by hundreds of programmers in the military. When the
button is clicked, the communications behavior is hard-coded and immutable:
the email is sent. However, you have also been instructed to allow the
programmers to repsond to the button click in other ways ... perhaps to
display a message, "the button was clicked" .... if you override OnClick
without calling base.OnClick, the latter opportunity is foreclosed; the
programmer is limited to the email being sent

public class SendTroopsButton : Button
{

protected override void OnClick(EventArgs args)
{
base.OnClick(args);
dispatchSendTroopsEmail();
}

}

if you use this class:
{
...
SendTroopsButton troopsButton = new SendTroopsButton();
troopsButton.OnClick += new EventHandler(displayMessage); // displays
message on form that button was clicked
...
}

displayMessage will ONLY be called when the button is clicked if you
included the base.OnClick(args) statement in your SendTroops class;
dispatchSendTroopsEmail() will always be called when the button is clicked
.... that's why you might need a base call
I agree with you fully on the "maestro" tag. I don't feel qualified to
approach Petzold directly out of respect for his time and respect for
his invaluable works.

he invites email ... but does not promise a reply ...

I don't know if you're focused on looking for a difference in behavior
between hosting the class in a DLL vs locally but that will not make a
difference ... the difference is in calling base.Method vs not calling it
and to see the difference you must attempt to handle the event independently
of the behavior specified in the override ... clearly there will be cases
where whatever executes in the override will cover all of the behavior
required and where you don't want independent handling of the event, in
which case of course you would not use a base call

I think Petzold's implied generic suggestion was that calling base is a good
idea so you don't foreclose handling the event .. he just didn't spell out
all the rationale.

L
 
M

Mick Doherty

Tom said:
To add to my confusion is another program within the same book:
Chapter 3, ColorFill.

There, you can find a similar base method call in the following:

protected override void OnFontChanged(EventArgs args)
{
base.OnFontChanged(args); // << similar base method call ?????
Padding = new Padding(Padding.Left, yDpi / 10 + Font.Height,
Padding.Right, Padding.Bottom);
}

Again, I run the program with and without the base method call and on
my system the resulting behavior is the same. Compiles correctly and
runs identically.

Using this example:

I don't have any of Charles' books so I can't refer to any examples in it,
but I very much doubt that the behaviour is the same when you omit the base
method call.

Changing the Font will cause a Paint event to be raised, but in this
specific example I assume that changing Padding will also cause a Paint
event.

Font is an ambient property. If you don't explicitly set it, then a control
will use it's Parent controls Font value.
When the parent font is changed the child controls will also be updated.
This may mean a resize of the child control as well as a repaint.
If you do not call the base.OnFontChanged() method then, in this case,
setting the Padding may well cause a repaint of the child controls, but it
will not cause them to be resized. If the control does not have any child
controls, then there may not be any advantage in calling the base method.

Some On* methods do not do anything other than raise an event. If you want
the event to be raised then either call the base method, or raise the method
yourself.

Unless you have intimate knowledge of the class and what it does in it's
base method, then it is best to call the method as not doing so may cause
other undesired behaviour which may go unnoticed until you see a specific
set of conditions.
 
T

Tom

The lights are now on!!

Thank you Liz & Mick.

Petzold was greatly enhancing the flexibility of the DLL contained
class by including a line of code that in the simplest of cases is not
needed.

I was too focused on: "What does this line of code do?" in this
*specific* case!

Liz -- Your example was perfect. It was my haste to understand and
respond back here that caused my confusion. I simply(and dumbly)
commented out the base class call in the override and ran it. Because
the base method in this particular program does nothing ... there was
no change in behavior. Your changing the nothing to something reveals
Petzold's point!!

The library user often does not have the source of the DLL and thus
can not modify the override function. Enhancements to the base methods
occur at the base level and require the override to execute them.

I had been frozen in confusion and now can move forward.

Thanks !!!!!!!!!!

-- Tom
 
T

Tom

Now that made me laugh !!

I should have but didn't recognize the name. I am not a computer
historian and that name is not on any computer texts I own ... so
Yahoo search revealed: simonyiCreatedHungarianNotation and was
instrumental in the Word and Excel development. Very impressive. Major
rich. Space tourist and endowed a couple of scientific professorship
programs.

Now he is all about "Intentional" programming.

http://www.edge.org/digerati/simonyi/simonyi_p2.html

From the above link >>

SIMONYI: I have been working on what we call "intentional
programming." It's very exciting. It has to do with professional
programming, so it's kind of hard to get into the details. It also
relates to the work of evolutionary biologist Richard Dawkins in a
fairly direct way. We are trying to create an ecology of abstractions.
Abstraction is really the most powerful tool that we have in thinking
about problems. An abstraction is a single thing, yet if it is a good
one, it can have many applications, even an infinite number of them.
So an abstraction may be looked at from one side as a compression of
many instances into one generality or from the other side as a special
purpose power tool that yields the solution for many problems. If one
could attach a dollar sign to this power, the economies would be
amazing: rivaling that of chips or application software itself.

That last paragraph sentence above deserves reading a few times.

I wish him luck!! Feed that algorithm 'how to conquer cold fusion' and
solve the world's energy requirements. Then cure all the major
illnesses. Then solve world wide racial issues. Hmmm ... does religion
promote racism? Then perhaps a transporter beam would be fun. What
next?
 
L

Liz

Now he is all about "Intentional" programming.

the entire MS culture is now about "intentional engineering" ... which makes
me wonder what it was previously about; was Windows accidental?
SIMONYI: I have been working on what we call "intentional
programming." It's very exciting. It has to do with professional
....

So an abstraction may be looked at from one side as a compression of
many instances into one generality or from the other side as a special
purpose power tool that yields the solution for many problems. If one
could attach a dollar sign to this power, the economies would be
amazing: rivaling that of chips or application software itself.

this is what can happen when your net worth exceeds $1 billion ... truly
frightening ... I don't know what Martha sees in the man ... what do they
talk about? intentional Christmas ornaments?
 

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

Top