On Jul 23, 11:40 pm, raylopez99 <raylope...@yah oo.comwrote:
raylopez99 <raylope...@yah oo.comwrote:
In that case I guess it's the end of the discussion.
I did learn a few things in this exchange, which I'll summarize
below. Thanks for replying.
I'm glad.
I didn't realize you were such a stickler for complete code, I assumed
you were just being obstinate. I'll make a mental note of it for any
future reference.
It really makes a huge difference. Apart from anything else, if you
can come up with a short, complete example you can cut and paste *all*
of it into a post, avoiding any spurious changes.
You claimed forms and console apps were "totally different". They're
not. Even the entry point is the same - a Main method.
OK, if you say so. I don't even know where "Main" is in Windows
anymore, but I assume it's there somewhere.
In a WinForms app generated by Visual Studio, it's in Program.cs.
Including Main in a class isn't the same as creating a nested class -
and it's *always* in a class (or struct) so it's not a "convention " -
it's part of how you *have* to define methods.
Yes, but it doesn't address the issue of scope, etc. But let's move
on.
If all you meant was that you wanted to see the Main method in a
different class, that would have been fine. It was your complaint that
it was "nested" in a class which was odd.
But I wrote the program in Windows Form application mode, not console
mode. I could reproduce a Windows Form error in Console mode, I would
be quite the experienced programmer, no?
Not really. It's quite a simple transformation, if you're not actually
using any WinForms code. In fact, you could just have deleted the
designer files, deleted the calls to InitializeCompo nent, made the
classes not derive from Form, and then change Program.cs to call a
method within your class instead of running Application.Run .
If you'd explained that you were having trouble doing the conversion,
I'd have helped with that - but instead you insisted that everything
was different in WinForms apps.
<snip>
If I'm that competent a programmer, I would not need you or anybody
else to spot errors in my code; I would not make errors in the first
place.
No, that's really not how it works. Being able to demonstrate
something in a console app really doesn't take much knowledge. If
console apps effectively scare you, it's well worth writing some.
They're a lot easier to work with than WinForms apps when you don't
actually need a GUI. For instance, displaying information is just a
matter of calling Console.WriteLi ne instead of fiddling around with
message boxes etc.
I strongly recommend that you play around with them a bit. One hint:
put a call to Console.ReadLin e() at the end of your Main method so you
can see what's happened before the program terminates. (I don't do
this for my simple console apps usually because I build and run them
from the command line, where it's not an issue. It's really just in
Visual Studio.)
<snip>
While you fail to use correct terminology, even after being corrected
on it, communication is difficult. Likewise it is harder to comment on
a program when I'm only given half the code.
But your lingo is not conducive to the free flow of information. It's
like first having to repeat a magic number before I get an answer.
You told me the magic number five posts ago, but I forgot it.
Then review the posts! There's not much point in me telling you
something if you completely ignore it and forget it. Learning the
right terminology is a vital part of learning how to communicate about
a programming language. Imagine if you were trying to learn English
grammar, but you kept calling nouns verbs... it would make everything
terribly confusing.
Study and commit to memory, I've added a few Easter Egg comments
tailored just for you Jon:
Here it is:
////////// START OF PARTIAL CLASS FORM1: Form
public partial class Form1 : Form
{
Class1 myClass1; //cannot comment out this line--compile error
<--do you know why, Jon?
Obviously - you're referring to it in the constructor.
Really? A constructor in my "book" is the stuff that appears in public
Form1 () {//here}, but I guess I'm using the wrong lingo again.
Anyway, moving right along...
Yes, and you were referring to it there - near the bottom. You also
referred to it in the event handling method - sorry that I didn't
mention that as well.
However, you could move the declaration to after the contructor and
methods - or even to a different file which also declares Form1 (again
as a public partial classs).
Oh, really? OK, I just tried this and it doesn't compile (sorry in
advance about the incomplete code, but you know how that goes)...
///////start
namespace MDIForms
{
Class1 myClass1; //// error CS0116: A namespace does not
directly contain members such as fields or methods
public partial class Form1 : Form
{
//Class1 myClass1; //manditory for compiling
//////end
It still needs to be within a class declaration for Form1 - but you
could have moved it to just before the end of the class, e.g. after
the event handling method.
I try to avoid doing it in other cases, however.'
OK, I did get that, I think, as I understand the code fragment you
gave is perfectly legal (this.something =something; is not the same as
something=somet hing;) and gives the intended result, unlike my
commented out code.
Yup. Using "this.myCla ss1" means "I want to refer to the instance
variable myClass1 belonging to "this" object, instead of a local
variable which happens to also have the name myClass1.
The default value of a reference type non-local variable is null. As
for whether it's "bad" that depends on the context. Sometimes it's
exactly what you want - but not in this case.
Understood. I even saw in a Windows App event handler some code like:
MyDialogForm01 dlgForm = new MyDialogForm01( );
//stuff deleted here
dlgForm = null; // at end of code; not strictly needed, apparently
some form of manual garbage collection
Avoid code like that. Setting a local variable to null at the end of
the method has no effect, and certainly doesn't trigger garbage
collection. In fact the object could have been collected before that
line of code, if nothing else references it.
(There are some situations involving captured variables where setting
a local variable to null *would* have an effect - probably an
unintended one - but that's a more complication situation. I mention
it only for completeness.)
Yes, you're using it to pass information to Form2. As we've already
discussed, there are other ways of doing that.
True enough, though in my mind other than the example of inheriting a
form, and using a method from a class that's nested in the base class,
I really don't see how. Far more flexible to pass objects--oops, I
meant variables--to the second or derived form. I mentioned in
passing that you can maybe use delegates/events between forms, but the
more I think about it, the more I see that getting the events
recognized might be a problem. Maybe you can insert "delegate <type>
VariableName (type)" throughout both forms, and maybe that will work,
but without seeing an example I'm not about to waste an hour or two
trying to find out. Besides there's a hoary tradition in C++ of using
the constructor to pass all kinds of information
<snip>
Certainly using a constructor this way is fine. Aside from anything
else, it's vital if you want to make the type immutable, which is
often a good thing.
Nope, the classes aren't hidden at all. To prove it, just write:
new Class1(0, "");
new Class2();
in the constructor. Obviously it won't do a lot of good (unless those
constructors do interesting things) but the fact that it compiles
proves that the classes aren't hidden.
OK, thanks for that terminology. *Hiding is not the best word, perhaps
'local variable overriding of outer scope (?) variables of the same
name'. *Or something like that. OK I got it. *Or maybe not. *Moving
right along...
No, "hiding" is the right word - it's class that was the wrong word.
The local variable certainly wasn't *overriding* the instance variable
- that would suggest some kind of odd local polymorphism. If you don't
like the word "hiding" then "shadowing" is also fine.
At that point variables myClass1 and mYClass2 would refer to the nested
classes; the constructor call to Class1 within the Form1 constructor
wouldn't compile as the appropriate constructor signature hasn't been
declared, and clikMeNewFToolS tripMenuItem_Cl ick wouldn't compile
because the types of the Form2 constructor call would be incompatible.
Interesting, thanks. *You left out an important detail--when there is
ambiguity, how can you tell the compiler to 'override' the ambiguity
and compile? *In C# there is no easy way, for example, if the Class1
and Class2 variables are in namespace XYZABC, you can maybe write
XYZABC.Class1 myClass1; etc., but everytime I tried this it doesn't
compile *(Update: *I see the 'this' pointer below solves some
ambiguity)
"this" will solve it to refer to variables, but if there's ambiguity
in the class names themselves, using the namespace is usually enough
to fix it. If it's still not (and there can be times where it's not
enough) you can use global::Namespa ce.Goes.Here.Cl assname
If that's *still* not enough (because you're referring to two types
which have the same fully qualified name but are in different
assemblies) you can use extern aliases - but try not to :)
Hiding is a perfectly fine word to use - but saying you're declaring a
class when you're actually declaring a variable is hugely misleading.
OK, noted. *If this is in your book I'll study it, but likely if not
I'll forget it five minutes after I post this thread.
This kind of thing isn't in my book, I'm afraid - my book is aimed at
people who already know C# 1 reasonably well. Hopefully I *use*
terminology accurately though, so it's possible that it'll sink in by
osmosis :)
(If you've already got C# 3.0 in a Nutshell then I'd stick with that
until you're reasonably comfortable with the C# 1 features. It's a
good book. If you want a bit more of a "deep dive" into the C# 2 and 3
features, that's when my book would be helpful.)
<snip>
then the program will work without a NullReferenceEx ception.
Wow! *You're good. *I played around and see what you're talking about,
even though I'm not 100% clear on why the 'this' pointer (the object
calling 'Form1()') makes such a difference, but maybe the object/
variable understand to use the 'outermost' Class1. *Leaving out the
'this' pointer did give a nice compiler warning CS0136, which, had I
seen it before, would have obviated having to write this entire thread
(though I guess I would not have learned as much).
Hopefully my explanation of the use of "this" above explained the
matter, but let me know if you want more detail (and a sample app :)
// here is what I played with, comments from compiler and hoving
ToolTips
this.myClass1 = new Class1(100, "heLlO1YouTube! "); //Class1
Form1.myClass1
Yup.
//failure to use 'this' above gives a compiler error: error CS0136: A
local variable named 'myClass1' cannot be declared in this scope
because it would give a different meaning to 'myClass1', which is
already used in a 'parent or current' scope to denote something else
I think you've got different code again then - because you'd normally
only see that if you had multiple scopes within the method, and
declared the variable twice within those scopes. For instance:
class ScopeDemo
{
int variable; // Instance variable
public void Method()
{
// Local variable - hides or shadows the instance variable
int variable;
{ // Create a new scope
// Declare another local variable - this causes CS0136
int variable;
}
}
}
// Class with Main in just so we can compile as a console app.
// Actually running this app does nothing. We could have
// removed this class and compiled as a class library instead.
class Test
{
static void Main() {}
}
That will generate CS0136. If you remove either of the local variable
declarations, it will compile. There will be warnings because we're
not actually *using* the variable, but it's only when there are
multiple local variable declarations that you see CS0136 - and that
would occur even without the instance variable existing at all.
Hope that helps,
Jon