.NET Forum / Languages / C# / November 2007
For future reference: nested classes and access modifiers (protected, protected internal)
|
|
Thread rating:  |
raylopez99 - 20 Sep 2007 16:43 GMT The below source code is just for future reference, since I had problems understanding the use of access modifiers "protected" and "protected internal" with the examples on the net. Nothing beats doing a demonstration program yourself however.
Actually the below example doesn't show how using "protected internal" will allow you access of a member from outside the namespace the member class is found in, but you get the picture.
Sorry for any line breaks, but I copied and pasted from Word.
Program shows: how even private members of a enclosing class can be accessed by the nested class enclosed by the enclosing class; how protected/ protected internal works; how you can instantiate either the nested class, the enclosing class, or both; how instantiation by "new" overrides and/or is required by a nested class, to access the enclosing class.
Frankly I think the access modifiers in C# are more confusing and can lead to spagetti code quicker than C++, but that's another matter.
RL
using System; using System.Collections.Generic; using System.Text;
namespace nestc001 {
/// <summary> /// Summary Using Nested classes with access modifier "protected internal" /// </summary> /// class NestedOuterClass1 { private int magic_no; public int magic_noPublic; public int[] arr_outerCl; public NestedInterClass0 mySeemingViolationInnerClass; public NestedInnerClassTWO my2ndInnerClassThatCanAccessPrivateMembersOfOuterClass;
public NestedOuterClass1() { magic_no = 1111111; magic_noPublic = 999; arr_outerCl = new int[3] { 111, 222, 333 }; mySeemingViolationInnerClass = new NestedInterClass0(69); //works, despite being protected, since 'protected AND internal' (more expansive) my2ndInnerClassThatCanAccessPrivateMembersOfOuterClass = new NestedInnerClassTWO();
} //end of constructor for outer class
protected int[] Function01NestedOuterClass1(NestedInterClass0 O) { arr_outerCl = new int[3]; arr_outerCl = O.arr_innerCl; return arr_outerCl; }
public int[] Function02NestedOuterClass2(NestedInterClass0 O) {
arr_outerCl = O.arr_innerCl; return arr_outerCl; }
public int[] interfaceFunction01NestedOuterClass1() { NestedInterClass0 Internal_ICl = new NestedInterClass0(); // BTW: Internal_ICl.// cannot see any outer class member here, since 'temp' and 'local', but other inner class mySeemingViolationInnerClass can! arr_outerCl = Function01NestedOuterClass1(Internal_ICl); return arr_outerCl; }
public int[] return_the_arr_outerCl_noMatterWhatItIs() { return arr_outerCl;
}
public void Access_even_internal_members() { // mySeemingViolationInnerClass.//nothing from outer class or second inner class accessible here // my2ndInnerClassThatCanAccessPrivateMembersOfOuterClass.jay = 0; }
// protected class NestedInterClass0 doesn't give sufficent privileged to any class other than the enclosed class (outer class) to run any function, even if labeled 'public', so changed to 'protected internal'
protected internal class NestedInterClass0 { public int j; public int[] arr_innerCl; public NestedInterClass0() { arr_innerCl = new int[3] { 10, 20, 30 }; j = 1001;
} public NestedInterClass0(int i) { j = i; arr_innerCl = new int[3] { 55, 66, 77 }; }
public int NestInnerC0Function() { return 1; } public int[] change_the_arr_innerCl() { for (int i = 0; i < 3; i++) { arr_innerCl[i] = i * i; //0,1,4
} return arr_innerCl; } }
public class NestedInnerClassTWO //second nested inner class, this time access modifier is public, so this class can access enclosing outer class private numbers { public int jay; public NestedInnerClassTWO() { jay = 1; // jay = NestedOuterClass1.//nothing! cannot access any members of outerclass }
public int MyNICTWOfunction () { NestedOuterClass1 myNOC1 = new NestedOuterClass1(); // instantiation req'd! // myNOC1.magic_no = 100000; //can override private number if you want... return myNOC1.magic_no; // no overriding, should get magic_no = 1111111;
} public int MyNICTWOfunction2() { NestedOuterClass1 myNOC1 = new NestedOuterClass1(); // instantiation req'd return myNOC1.magic_noPublic;
} } }
public static class Tester { public static void MMain() { int[] TestArr = new int[3];
NestedOuterClass1 myNestedOuterClass1 = new NestedOuterClass1();
NestedOuterClass1.NestedInterClass0 myNIC0 = new NestedOuterClass1.NestedInterClass0(); Console.WriteLine("myNIC0 reached, since 'protected internal',NestedInterClass0, with magic #:{1}, magic# public: {2}!", myNIC0.NestInnerC0Function(), myNestedOuterClass1.my2ndInnerClassThatCanAccessPrivateMembersOfOuterClass.MyNICTWOfunction(), myNestedOuterClass1.my2ndInnerClassThatCanAccessPrivateMembersOfOuterClass.MyNICTWOfunction2());
TestArr = myNestedOuterClass1.arr_outerCl; int ll01 = TestArr.Length;
for (int i = 0; i < ll01; i++) { Console.WriteLine("TestArr[{0}] is: {1}", i, TestArr[i]);
}
TestArr = myNestedOuterClass1.interfaceFunction01NestedOuterClass1();
for (int i = 0; i < ll01; i++) { Console.WriteLine("TestArr(2)[{0}] is: {1}", i, TestArr[i]);
}
myNIC0.change_the_arr_innerCl();
myNestedOuterClass1.Function02NestedOuterClass2(myNIC0); TestArr = myNestedOuterClass1.return_the_arr_outerCl_noMatterWhatItIs();
for (int i = 0; i < ll01; i++) { Console.WriteLine("TestArr(3)[{0}] is: {1}", i, TestArr[i]);
}
} } }
/* /////////// output, after running class Tester from inside of main():
myNIC0 reached, since 'protected internal',NestedInterClass0, with magic #:11111 11, magic# public: 999! TestArr[0] is: 111 TestArr[1] is: 222 TestArr[2] is: 333 TestArr(2)[0] is: 10 TestArr(2)[1] is: 20 TestArr(2)[2] is: 30 TestArr(3)[0] is: 0 TestArr(3)[1] is: 1 TestArr(3)[2] is: 4 Press any key to continue . . . */
Jon Skeet [C# MVP] - 20 Sep 2007 16:47 GMT <snip>
> Program shows: how even private members of a enclosing class can be > accessed by the nested class enclosed by the enclosing class; how > protected/ protected internal works; how you can instantiate either > the nested class, the enclosing class, or both; how instantiation by > "new" overrides and/or is required by a nested class, to access the > enclosing class. Could you explain what you mean by the last point? I don't understand what you mean, but I *suspect* you've misunderstood something.
Jon
raylopez99 - 20 Sep 2007 16:52 GMT > > Program shows: how even private members of a enclosing class can be > > accessed by the nested class enclosed by the enclosing class; how [quoted text clipped - 5 lines] > Could you explain what you mean by the last point? I don't understand > what you mean, but I *suspect* you've misunderstood something. Thanks Jon. I'd be happy to, since I'm learning:
This part:
*/
public int MyNICTWOfunction () { NestedOuterClass1 myNOC1 = new NestedOuterClass1(); // instantiation req'd! // myNOC1.magic_no = 100000; //can override private number if you want... return myNOC1.magic_no; // no overriding, should get magic_no = 1111111; }
/*
Without the "new NestedOuterClass1()" you cannot have "myNOC1.magic_no = 100000;" in the next line.
RL
Jon Skeet [C# MVP] - 20 Sep 2007 19:13 GMT > > > Program shows: how even private members of a enclosing class can be > > > accessed by the nested class enclosed by the enclosing class; how [quoted text clipped - 26 lines] > Without the "new NestedOuterClass1()" you cannot have > "myNOC1.magic_no = 100000;" in the next line. No, of course you can't - you can't access an object without creating it. This isn't behaviour which is specific to nested classes or anything like that though.
But you're using incorrect terminology when you say: "can override private number if you want". Overriding is part of polymorphism. You can change the value of the field, but that's nothing to do with overriding.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Peter Duniho - 20 Sep 2007 17:15 GMT > [...] > how instantiation by > "new" overrides and/or is required by a nested class, to access the > enclosing class. As Jon wrote, you may have misunderstood something.
Instantiation of _any_ class is required in order to access instance members, regardless of where that class is declared. So this is not particular to the question of nested classes.
I think the important thing here, and perhaps what may be the confusing aspect, is that having a class declared within another class does not create a new instance of that contained class automatically when you have an instance of the containing class.
Or put another way: anything that would simply be a declaration, like code to declare a class, a struct, an interface, a delegate type, etc. is always just a declaration of that thing, even when found inside the declaration of some other thing. It affects the visibility and scope of the thing you are declaring, but the thing is not itself automatically instantiated, just as the same kind of thing is not automatically instantiated when declared at the outermost level of the namespace.
I'm also not clear on why you believe access modifiers would result in spaghetti code, but that's not related to the above (I think :) ).
Pete
raylopez99 - 20 Sep 2007 18:33 GMT > Instantiation of _any_ class is required in order to access instance > members, regardless of where that class is declared. So this is not > particular to the question of nested classes.
> I think the important thing here, and perhaps what may be the confusing > aspect, is that having a class declared within another class does not > create a new instance of that contained class automatically when you > have an instance of the containing class Yes, but you can compile such a code without new. But in the example I showed, it would not even compile without a new.
For example, see here (from the same code). Note the "Internal_ICl" is "local" and cannot access any outer class member, hence will not compile if you try, but the other inner (nested) classes can, because of their placement in the code, even regardless of instantiation ('new'), since they all use 'new'.
*/
public int[] interfaceFunction01NestedOuterClass1() { NestedInterClass0 Internal_ICl = new NestedInterClass0();
// BTW: Internal_ICl.// cannot see any outer class member here, since 'temp' and 'local', but other inner class mySeemingViolationInnerClass can!
arr_outerCl = Function01NestedOuterClass1(Internal_ICl); return arr_outerCl; } /*
Also, and somewhat beside the point, base classes are always implicitly instantiated (it seems to me) when a derived class is called, so a nested class, like you say, seems to require the same thing, but it doesn't.
> I'm also not clear on why you believe access modifiers would result in > spaghetti code, but that's not related to the above (I think :) ). True, I'll reserve my rant for another day, but it boils down to too many choices (which a "GOTO" will also give you).
RL
Jon Skeet [C# MVP] - 20 Sep 2007 19:20 GMT > > Instantiation of _any_ class is required in order to access instance > > members, regardless of where that class is declared. So this is not [quoted text clipped - 28 lines] > return arr_outerCl; > } You can't see any enclosing class members via Internal_IC1 because it's not an instance of the enclosing class - it's an instance of the nested class.
It's not clear to me where you think the difference is though, or what it's got to do with creating a new object.
Comments in your code like "//second nested inner class, this time access modifier is public, so this class can access enclosing outer class private numbers" are completely wrong. A nested class can *always* access private variables of the enclosing class, regardless of its own declared access.
I'm afraid your code is too convoluted to make much sense out of it, but I think you're still a way off understanding what's available.
> /* > > Also, and somewhat beside the point, base classes are always > implicitly instantiated (it seems to me) when a derived class is > called, so a nested class, like you say, seems to require the same > thing, but it doesn't. It doesn't require the same thing because an instance of a nested class is completely different from an instance of an enclosing class. Aside from the special access available, they're just two completely separate types.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Peter Duniho - 20 Sep 2007 19:27 GMT >> I think the important thing here, and perhaps what may be the confusing >> aspect, is that having a class declared within another class does not [quoted text clipped - 3 lines] > Yes, but you can compile such a code without new. But in the example > I showed, it would not even compile without a new. There is no difference. No matter where the class is declared, you cannot access instance members without an instance of the class.
If you have code that won't compile with "new" -- that is, without creating an instance -- then that code won't compile no matter where you put it. The nested class is a red herring; it has nothing do with whether you can access an instance member.
> For example, see here (from the same code). Note the "Internal_ICl" > is "local" and cannot access any outer class member, hence will not > compile if you try, but the other inner (nested) classes can, because > of their placement in the code, even regardless of instantiation > ('new'), since they all use 'new'. I don't understand the code example you've provided. The method is in your outer class, not the inner class. So it doesn't in any way offer any insight into what sorts of things can be accessed from within the inner class.
You seem to be getting confused about an instance having access to things versus the actual methods within a class having access to things. Where the instance is created has nothing to do with what it can access. Only where the methods are declared affects access.
> Also, and somewhat beside the point, base classes are always > implicitly instantiated (it seems to me) when a derived class is > called, so a nested class, like you say, seems to require the same > thing, but it doesn't. Here too you seem to misunderstand what's going on.
First, let's assume when you wrote "when a derived class is called", you actually mean "when a derived class is instantiated". The reason I say that is that simply calling a method on a class never implicitly instantiates any class, base or derived. To call an instance method, you must already have an instance; to call a method in a class without an instance, the method must be a static method, and calling that method will not implicitly instantiate either the derived class or the base class.
So, back to your statement above:
The base class is not a separate instance from the derived class. It's all part of the same instance. When you instantiate the derived class, the base class is _part_ of that instance. There's no other implicitly instantiated instance of the base class; it's part and parcel of the derived class.
So, when you instantiate the derived class, it's not that the base class is implicitly instantiated so much as it is that the base class, being part of the derived class, is explicitly instantiated as part of the derived class.
Using a classic OOP example: consider the class hierarchy with base class Human and derived classes Man and Woman. When a Man or Woman is created, it's not that there's some separate Human that is also created; the Man or Woman _is_ a Human. By creating a Man or a Woman, you necessarily create something that is either a Man or is a Woman but which is always _also_ a Human.
Finally, with respect to the access modifier thing you're looking at, note that a nested class can derive from a non-nested class. In this case, _only_ the methods declared in the derived nested class will have access to the containing class. The base class methods do not gain access simply by virtue of being inherited from within the containing class. Again, this is because access has everything to do with where the method in question is declared, and nothing at all to do with where the instance is actually instantiated.
Pete
raylopez99 - 20 Sep 2007 21:07 GMT [interesting, albeit verbose, thanks]
Well, consider this code then:
//////////// start of code //////////////
class Outer1 { private int A; public Outer1(int a) { A = a; } public class Nested1 { public void DisplayA(Outer1 o) { System.Console.WriteLine("this is A:{0}", o.A); } } }
//////////// middle of code ////////////////////////
public static void MMain2() { Outer1 o1 = new Outer1(4); Outer1.Nested1 n1 = new Outer1.Nested1(); // default instantiation (not even a member function) n1.DisplayA(o1); //will print "this is A: 4" }
////////////// end of code /////////////////////
If you comment out from "middle of code" to"end of code", the stuff from "start of code" to "middle of code" WILL compile, without a single "new" instantiation, and it's a nested class. Put that into your pipe and smoke it! LOL. Of course, it won't 'do anything' without the MMain2() code, but that's another story--I'm talking about compile errors.
The secret to successful compiling of this nested class code is a sort of 'forward reference' (using a C++ term) in the two classes (enclosing, Outer1, and nested, Nested), namely, the forward reference of "Outer1 o" in the Nested nested class. BTW, if for some reason one of the methods in the enclosing class, Outer1, also needed to access some member variable or function from the nested class, Nested, you would likewise need such a 'forward reference'. And, contrary to the implication (in my mind), this is not really a 'access problem' since this line will not compile if placed in the nested class Nested: int nested_int = Outer1.A; //won't compile, even with "Outer1." specified as a prefix
This problem, BTW, and offtopic, is not true for derived-inhereited classes, but, as has been said, this is a completely seperate topic that only 'optically' looks similar to this problem in this post, but I mention it since it does strike a chord in one's mind that can lead to errors.
Therein is the secret then, and why I was having problems (since this example was my first nested class--I was avoiding them over the years for good reason).
In short, to compile a nested and enclosing class, you need to have a "nexus" between nested and enclosing classes. The "nexus" can be one of two things:
(1) an instantiation, using 'new' of one or both classes (enclosing and nested) in both enclosing and nested classes, as per the posters in this thread, including Pete and Jon, or,
(2) what I said about 'forward reference' above, see the example above.
I had the same problem once in C++ when I was trying to "link" two classes, each to one another, before they were instantiated using 'new', and I ended up successfully doing this by using pointers, with forward references of pointers between the classes.
I consider this post the last word on this subject and deem this thread closed. Thanks for your replies.
Thus speaketh Ray Lopez. So it is written, so it shall come to pass.
RL
Jon Skeet [C# MVP] - 20 Sep 2007 21:23 GMT > [interesting, albeit verbose, thanks] > > Well, consider this code then: <snip>
> If you comment out from "middle of code" to"end of code", the stuff > from "start of code" to "middle of code" WILL compile, without a > single "new" instantiation, and it's a nested class. Put that into > your pipe and smoke it! LOL. Of course, it won't 'do anything' > without the MMain2() code, but that's another story--I'm talking about > compile errors. Um, that's because you're passing in a reference to an object (the parameter o).
It's not a "forward reference" - it's just a parameter.
Again, this has *nothing* to do with nested classes.
The reason you can't use Outer1.A is that A is an *instance* variable, not a *static* variable. Again, nothing to do with nested classes.
<snip>
> I consider this post the last word on this subject and deem this > thread closed. Well, you can if you like - but it still sounds like you're confused. Particularly the business you wrote about the "nexus" - it has *nothing* to do with types being nested or not: if you want to access an instance member of a type, you need an instance of that type. That's true of *all* types, no matter *where* you reference them from.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Peter Duniho - 20 Sep 2007 22:45 GMT > [interesting, albeit verbose, thanks] I am amused that you would take the time to observe my post as being "verbose" and then ramble on yourself.
> [...] > If you comment out from "middle of code" to"end of code", the stuff > from "start of code" to "middle of code" WILL compile, without a > single "new" instantiation, and it's a nested class. So what? The code doesn't need an explicit "new" statement for there to be an instance. In the code remaining, you pass in an instance of the class being referenced.
> [...] > The secret to successful compiling of this nested class code is a sort > of 'forward reference' (using a C++ term) in the two classes > (enclosing, Outer1, and nested, Nested), namely, the forward reference > of "Outer1 o" in the Nested nested class. As Jon says, this has absolutely nothing to do with the concept of forward references in C++. C# doesn't even have the concept of forward references, because no matter where you declare something, the compiler will find it. There aren't header files, there's no explicit preprocessing, etc.
In C++ a forward reference has to do with providing necessary declarations so that at the point at which the compiler comes across the code, it knows how to interpret it.
In C# there's no such defined order of processing the code, and so no such thing as forward references is necessary.
As far as the code you're talking about, there's no "secret" at all. Class Nested1 has complete access to all members of class Outer1, so in Nested1.DisplayA the code has complete access to all members of class Outer1, including Outer1.A. It's not a "secret"...it's just a simple matter of accessibility.
Just as this code would work:
class Outer1 { private int A;
public Outer1(int a) { A = a; }
public void DisplayA(Outer1 o) { System.Console.WriteLine("this is A:{0}", o.A); }
public void DisplayA() { System.Console.WriteLine("this is A:{0}", A); }
static public void Test() { Outer1 o1 = new(5), o2 = new(10);
o1.DisplayA(o2); o1.DisplayA(); } }
So too does the code you posted.
In the above code, if you call the Test() method, you will get the following output:
this is A:10 this is A:5
In the first DisplayA() method, it uses the value from the object passed in. In the second DisplayA() method, it uses the value of the instance used to call the method.
Like I wrote before, access doesn't have anything to do with the instance. It has to do with the code that's being executed. Even if you are executing an instance method, its access is not limited to members within the same instance. All that matters is whether the method itself (not the instance using the method) has access to the member.
If you create an instance method, then yes...you need an instance of that class's object to call the method. But that doesn't mean that the instance is required in order to access some other class's member; all it means is that you declared the method as an instance method, and so an instance is required.
If you don't want to require an instance, that's easy: just make the method static. It has nothing to do with the access modifiers. It has everything to do with whether the method is an instance method or not.
> BTW, if for some reason one > of the methods in the enclosing class, Outer1, also needed to access > some member variable or function from the nested class, Nested, you > would likewise need such a 'forward reference'. Again, there's no such thing as a forward reference in C#. And if you wanted Outer1 to be able to access something in Nested1, the access modifier for that thing in Nested1 would have to be internal or public. Outer1 doesn't have access to private or protected members of Nested1.
Simply declaring some method within Outer1 that takes a Nested1 object as a parameter, the converse of what is presented in the code you posted, would not be sufficient. That alone should emphasize the fact that it's not the code you posted that makes the difference; it's how the access modifiers work and _where_ that code exists.
> And, contrary to the > implication (in my mind), this is not really a 'access problem' since > this line will not compile if placed in the nested class Nested: int > nested_int = Outer1.A; //won't compile, even with "Outer1." specified > as a prefix That's right. Because A is not a static member of Outer1. It would compile if you made A a static member.
The fact that you can create a different compile error using incorrect syntax doesn't in any way invalidate the fact that the question of whether Nested1 has access to Outer1 members is exactly an access problem. That's what "access" is all about.
> This problem, BTW, and offtopic, is not true for derived-inhereited > classes, but, as has been said, this is a completely seperate topic > that only 'optically' looks similar to this problem in this post, but > I mention it since it does strike a chord in one's mind that can lead > to errors. Inheritance and nested classes are completely different concepts. You are right that it is a mistake to consider behavior in one concept to be at all relevant to behavior in the other concept.
> Therein is the secret then, and why I was having problems (since this > example was my first nested class--I was avoiding them over the years > for good reason). You are still having problems, IMHO.
> In short, to compile a nested and enclosing class, you need to have a > "nexus" between nested and enclosing classes. The "nexus" can be one [quoted text clipped - 6 lines] > (2) what I said about 'forward reference' above, see the example > above. There is no such thing as a "forward reference" in C#. The _ONLY_ way to get at an instance member of ANY class is to have an instance of that class. You can pass it as a parameter, or it can be a variable (created locally, kept in a field, etc.), or it can be implicit (when the method itself is an instance member of the same instance you want to get at and you call the method using that instance). But no matter what, you _MUST_ have an instance.
In your example, you are trying to call an instance method, and so you need an instance of the class. But if all you're doing in that method is accessing data in some _other_ instance, there's no reason to make that method an instance method. It could just as easily be a static method, and as a static method you could call it directly via the class name (eg "Nested1.DisplayA") without instantiating it.
> I had the same problem once in C++ when I was trying to "link" two > classes, each to one another, before they were instantiated using > 'new', and I ended up successfully doing this by using pointers, with > forward references of pointers between the classes. In C++, if you have two class members that reference each other (whether because you store a class member of a type of the other class, or simply have a function in the class that uses the type, or whatever), then yes, you do need a forward reference so that each class knows about the other class even if you don't have a full class definition compiled yet.
But that has absolutely nothing to do with what's going on here.
> I consider this post the last word on this subject and deem this > thread closed. Thanks for your replies. > > Thus speaketh Ray Lopez. So it is written, so it shall come to pass. You may think it's the last word. But all that means is that you are coding without a clue.
Sorry to put it so bluntly, but you asked a question and then refused to accept the answers, even though it's pretty clear you don't know what you're talking about. If you ever want to get good at programming, that's an attitude you are going to have to abandon.
Pete
raylopez99 - 21 Sep 2007 00:38 GMT > > [interesting, albeit verbose, thanks] > > I am amused that you would take the time to observe my post as being > "verbose" and then ramble on yourself. But my ramble is shorter than yours, in this case shorter is better! But I appreciate your posts anyway, though they tend to be a bit simplistic.
> > [...] > > If you comment out from "middle of code" to"end of code", the stuff [quoted text clipped - 4 lines] > be an instance. In the code remaining, you pass in an instance of the > class being referenced. Exactly! Isn't that what I said? One of TWO ways, the other being a "new" statement.
> > [...] > > The secret to successful compiling of this nested class code is a sort [quoted text clipped - 7 lines] > will find it. There aren't header files, there's no explicit > preprocessing, etc. Call it what you want, call it macaroni. I'm a rapid coder, not a software engineer. I'll let you and Donald Knuth fight over the nomenclature.
> In C++ a forward reference has to do with providing necessary > declarations so that at the point at which the compiler comes across the [quoted text clipped - 8 lines] > Outer1, including Outer1.A. It's not a "secret"...it's just a simple > matter of accessibility. Hold on a minute--you're simply repeating that a nested class has all the access to the private members of the enclosing class...you could have said that in one sentence, like I just did. But the issue here is whether something will compile, not a truism of nested classes.
> Just as this code would work: > [quoted text clipped - 25 lines] > } > } Yeah, nice, but there's no nested class in your example. This whole thread is about nested classes. But I see what you're driving at I think: that a nested class is like an instantiation of any other class, and can be treated as such. But this point is trivial, since the 'big deal' in nested classes is accessibility, in particular when using access modifiers "protected" and "protected internal" for the nested class.
> So too does the code you posted. > [quoted text clipped - 7 lines] > in. In the second DisplayA() method, it uses the value of the instance > used to call the method. Yes, standard textbook procedure. And when this clashes with nested class nomenclature, as it surely will (see below), it creates the disconnect that prompted my original post.
> Like I wrote before, access doesn't have anything to do with the > instance. It has to do with the code that's being executed. Even if > you are executing an instance method, its access is not limited to > members within the same instance. All that matters is whether the > method itself (not the instance using the method) has access to the member. This is a consequence of C#'s confusing use of public/private/ protected for members rather than just for classes, but that's a post for another day. It's also off-topic to nested classes (this post).
> If you create an instance method, then yes...you need an instance of > that class's object to call the method. But that doesn't mean that the [quoted text clipped - 5 lines] > method static. It has nothing to do with the access modifiers. It has > everything to do with whether the method is an instance method or not. Actually I did make the method static in some code I haven't posted, and I had so many compile errors I had to switch to non-static. Static creates huge problems in your code, for reasons too numerous to mention, but one is that you cannot seem to inhereit static. '.
> Again, there's no such thing as a forward reference in C#. And if you > wanted Outer1 to be able to access something in Nested1, the access > modifier for that thing in Nested1 would have to be internal or public. > Outer1 doesn't have access to private or protected members of Nested1. But my book sez to use protected and protected internal for nested classes Pete! For Pete's sake, who to believe? You or book? Book sez eye.
[ repetitive stuff deleted--good, but a bit verbose--thanks anyway]
> > Thus speaketh Ray Lopez. So it is written, so it shall come to pass. > [quoted text clipped - 7 lines] > > Pete I don't refuse answers, I make assertions and back them with evidence. But I don't think your verbose "hand waving" replies are without value. In fact, I very much appreciate what you say, and it does jog my mind--kind of like a scoutmaster telling you the basics of survival. But, it's a little too simplistic for me. Perhaps, since you are so expert (I'm not doubting you're expert BTW), you've forgotten how to explain things to beginners. I have that problem with chess--I'm too advanced to be a good teacher.
BTW, here is what I found in my latest version of the "nested class problem" (one reason I've avoided using them--they're a pain).
Note carefully the comments below.
RL /////////////////////////////////////////////////////////////////////////////////////////////////////////////// using System; // Nested class example // September 20, 2007 using System.Collections.Generic; using System.Text;
namespace nestc001 { class Outer1 { private int A; private int jay; public int jayouterpublic; Nested1 myNested1; public Outer1(int a) { //myNested1 = new Nested1(); //compiles OK, but strictly speaking not needed (see below)
// myNested1.jay2; //won't compile since not on RHS - error CS0201: Only assignment, call, increment, decrement, and new object expressions can be used as a statement
int ktemp = myNested1.jay2; //compiles? Yes, since on RHS-- EVEN ALONE!!! (no need for myNested1 = new Nested1(); )[as a practical matter you'll get a null pointer unless you use 'new', but that's another matter]
//int ktemp3 = myNested1.jay3; //won't compile; can't reach jay3 due to access 'private'
A = a; } public Outer1() { A = 1000; jay = jayouterpublic = 1001; } protected internal class Nested1 { public int jay2; private int jay3;
//int nested_int = Outer1.A; //won't compile
public Nested1() { jay2 = jay3 = 101;
Outer1 myOuter01 = new Outer1(10);
// myOuter01.jay;//? compiles-No! since "alone", and not on RHS, you get error CS0201
// myOuter01.jayouterpublic;//?compiles? No -you get error CS0201
jay2 = myOuter01.jay; //compiles? yes, if on RHS
jay2 = myOuter01.jayouterpublic; //compiles? yes, but only if on RHS
} public void DisplayA(Outer1 o) { //o.jay; //compiles? No, error CS0201 // o.jayouterpublic; //compiles? - no CS0201 error // o.A;//compiles? No! by itself, needs to be on RHS int j = o.A;//compiles? Yes, if on RHS--this is important System.Console.WriteLine("this is A:{0}", o.A); } } }
} ////////////////////////////////////
Peter Duniho - 21 Sep 2007 02:16 GMT > But my ramble is shorter than yours, in this case shorter is better! > But I appreciate your posts anyway, though they tend to be a bit > simplistic. I am amused once again. This time with your statement that my posts are, at the same time, too simplistic and yet not simple enough to explain things to a beginner.
For what it's worth, while I readily admit that it is possible to have too much experience when trying to explain concepts, I have in fact had a fair amount of ongoing success teaching a variety of things to people, including C# and .NET topics.
There are certainly better teachers around than I am, but sometimes when a student isn't "getting it", it's partly their fault too.
>>> [...] >>> If you comment out from "middle of code" to"end of code", the stuff [quoted text clipped - 6 lines] > Exactly! Isn't that what I said? One of TWO ways, the other being a > "new" statement. No, it's nothing like what you said.
The "forward reference" isn't a way, because no such thing exists in C#, and in any case what you are calling a "forward reference" is simply an example of instantiation. The other "way" isn't a way, because it's silly to think that you would create a new instance just for the purpose of running some code that doesn't otherwise need an instance. That's a terrible way to design code.
In any case, _neither_ is actually important with respect to how a contained class may access members of a containing class. The only reason an instance is required in the code example you provided is that you declared the members in a way that requires an instance.
If you intend to be able to access a member without an instance, that's trivial to do. Just make the member static.
> Call it what you want, call it macaroni. I'm a rapid coder, not a > software engineer. I'll let you and Donald Knuth fight over the > nomenclature. You are free to pick random phrases with existing well-defined meanings and use them in entirely contexts, of course. But when you do so, keep in mind that people will either have no idea what you're talking about, or think you yourself have no idea what you're talking about, or both.
> Hold on a minute--you're simply repeating that a nested class has all > the access to the private members of the enclosing class...you could > have said that in one sentence, like I just did. All due respect, you never said anything like that. You have not made any statement that would lead us to believe that you actually understand how the relationship between a containing class and a contained class works, and especially you have not made any statement that makes clear that you understand that the existence of an instance has absolutely nothing to do with accessibility (quite the contrary, you seem to think it's related somehow).
And yes, I have tried to state the same thing in multiple, different ways. This is a classic teaching technique, since different students will respond to different language.
> But the issue here > is whether something will compile, not a truism of nested classes. No. The issue of whether something compiles or not is not at all a question. You cannot run code that doesn't compile, so getting it to compile is a given. The goal is not simply to get the code to compile, it's to get it to WORK.
Based on your original post, the issue very much IS "a truism of nested classes".
> Yeah, nice, but there's no nested class in your example. You're right, there's not. That's the whole point of the example.
> This whole > thread is about nested classes. But I see what you're driving at I > think: that a nested class is like an instantiation of any other > class, and can be treated as such. No, that's not what I'm driving at. There are at least a couple of points my example was meant to make:
1) That accessibility of members of a containing class by a contained class is identical to the accessibility by the containing class itself.
2) That methods that have access to members of a class can access those members whether they are operating on the instance implicit in the call to the method, or on an instance that was passed explicitly to the method.
You don't need to make a single instance of any class to demonstrate accessibility, so instantiation really doesn't have anything to do with accessibility.
> But this point is trivial, since > the 'big deal' in nested classes is accessibility, in particular when > using access modifiers "protected" and "protected internal" for the > nested class. I disagree. First of all, one "big deal" of nested classes is that they can be treated as closely tied to the containing class. A public nested class is exposed as something that is "part of" the containing class, rather than simply being one that works with the containing class. Or it could be hidden within the containing class (protected or private for example), used only by the containing class. This prevents the class from being used inappropriately by other classes, for example.
The fact that the contained class has access to the containing class's members is not the "big deal". If anything it is, IMHO, simply a natural consequence of creating a consistent language definition. If a contained class did not have access to the containing class's members, most of the reason for making a contained class would still exist.
> Yes, standard textbook procedure. And when this clashes with nested > class nomenclature, as it surely will (see below), it creates the > disconnect that prompted my original post. I don't see any clash. If you would like to demonstrate the "clash", you should create a more concise, less-ambiguous example and very be clear about where it is you perceive the "clash" to be.
> This is a consequence of C#'s confusing use of public/private/ > protected for members rather than just for classes, but that's a post > for another day. It's also off-topic to nested classes (this post). How can a discussion of access modifiers be off-topic in a thread that is specifically about access modifiers? And how is C#'s use of access modifiers different from C++'s similar access modifiers? That is, yes there are some specific differences, but the basic idea is the same in both languages.
> Actually I did make the method static in some code I haven't posted, > and I had so many compile errors I had to switch to non-static. Without seeing what you tried, it's hard to know whether you really "had to switch to non-static". Suffice to say, the code you did post could easily be fixed with the application of the "static" keyword, without introducing compiler errors.
> Static creates huge problems in your code, for reasons too numerous to > mention, but one is that you cannot seem to inhereit static. Yes, you can't inherit static classes. In most cases, that is not a "huge problem" and certainly that doesn't appear to be an issue in the example of code you've posted.
It is patently false that "static creates huge problems in your code"; in fact, if what you want to do is access something without an instance, "static" is the only way to solve that and it works very well without creating any problems at all, never mind "huge" ones.
There are specific limitations of static, but they are hardly "too numerous to mention".
The fact that you would make that claim simply illustrates how much more you have to learn about proper use of static classes and members.
>> Again, there's no such thing as a forward reference in C#. And if you >> wanted Outer1 to be able to access something in Nested1, the access [quoted text clipped - 4 lines] > classes Pete! For Pete's sake, who to believe? You or book? Book > sez eye. What book? What _exactly_ does it say? Use "protected" for what?
If your book says something other than what I wrote above and which you quoted, the book is wrong. The contained class has access to members of the containing class regardless of access modifier, but the converse is not true.
I suspect the book does not actually contradict what I wrote, and that you are simply misunderstanding it.
> I don't refuse answers, I make assertions and back them with > evidence. That's not true. The post to which I replied made false assertions, backed with code that didn't have anything to do with what you were claiming, never mind support your assertions. And you very much did refuse the answers that had been given to you.
> [...] > BTW, here is what I found in my latest version of the "nested class > problem" (one reason I've avoided using them--they're a pain). Perhaps you are finding them to be a pain because you are misusing them.
> Note carefully the comments below. I have. I don't understand what point you're trying to make, and I especially don't understand your desire to obfuscate whatever point it is you _are_ trying to make with a bunch of pointless statements (that is, every CS0201 error line that you included, none of which have anything to do with the question of nested classes or access modifiers).
As far as the specific comments go...
> RL > /////////////////////////////////////////////////////////////////////////////////////////////////////////////// [quoted text clipped - 14 lines] > //myNested1 = new Nested1(); //compiles OK, but strictly > speaking not needed (see below) It _is_ strictly needed if you intended to use the myNested1 variable to call an instance method in the Nested1 class.
> // myNested1.jay2; //won't compile since not on RHS - > error CS0201: Only assignment, call, increment, decrement, and new > object expressions can be used as a statement Why would you want such a statement anyway?
> int ktemp = myNested1.jay2; //compiles? Yes, since on RHS-- > EVEN ALONE!!! (no need for myNested1 = new Nested1(); )[as a practical > matter you'll get a null pointer unless you use 'new', but that's > another matter] This is a great example of why just because the code compiles, that doesn't mean you've done something that makes sense.
> //int ktemp3 = myNested1.jay3; //won't compile; can't > reach jay3 due to access 'private' Indeed. As I've said already, the containing class does not have access to private members in the contained class.
> A = a; > } [quoted text clipped - 8 lines] > > //int nested_int = Outer1.A; //won't compile No, of course not. A is an instance member and as such requires an instance. If you want to refer to A using the class name, you need to make A static.
> public Nested1() > { [quoted text clipped - 4 lines] > // myOuter01.jay;//? compiles-No! since "alone", and > not on RHS, you get error CS0201 Again, so? Why would you want that line of code anyway?
> // myOuter01.jayouterpublic;//?compiles? No -you get > error CS0201 Ditto.
> jay2 = myOuter01.jay; //compiles? yes, if on RHS Of course. As I wrote, the contained class has access to private members of the containing class.
> jay2 = myOuter01.jayouterpublic; //compiles? yes, but > only if on RHS This would compile anywhere, since Outer1.jayouterpublic is a public member.
> } > public void DisplayA(Outer1 o) > { > //o.jay; //compiles? No, error CS0201 Again, a useless line of code. Why is the fact that any of these don't compile of any value in this discussion?
> // o.jayouterpublic; //compiles? - no CS0201 error Ditto.
> // o.A;//compiles? No! by itself, needs to be on RHS Ditto. For the sixth time.
> int j = o.A;//compiles? Yes, if on RHS--this is > important Of course this compiles. The contained class has access to all members of the containing class, regardless of the access modifier for the member of the containing class.
> System.Console.WriteLine("this is A:{0}", o.A); Ditto.
> } > } > } > > } > //////////////////////////////////// So. What was the point in any of the code? What is it that you're trying to demonstrate? In what way does the above code support your statement that "nested classes are a pain"?
Pete
raylopez99 - 21 Sep 2007 11:32 GMT > So. What was the point in any of the code? What is it that you're > trying to demonstrate? In what way does the above code support your > statement that "nested classes are a pain"? > > Pete Thanks for commenting my code example. It suppliments what I learned by by myself.
Bottom line: nested classes are a pain and "composite classes" are better, as is "inhereited classes", except in those rare instances where you want the nested class to access the private members of the containing class.
Bye
RL
Jon Skeet [C# MVP] - 21 Sep 2007 11:53 GMT > Bottom line: nested classes are a pain and "composite classes" are > better, as is "inhereited classes", except in those rare instances > where you want the nested class to access the private members of the > containing class. Nested classes are useful in a number of situations, and are no more "painful" than normal classes. Comparing them to composition and inheritance is a complete red herring, because they're used for very different purposes.
Occasionally it's very handy to have access to private members in the enclosing class, but *also* making a nested class gives an indication of the context in which a class is relevant.
Jon
raylopez99 - 22 Sep 2007 09:06 GMT > > Bottom line: nested classes are a pain and "composite classes" are > > better, as is "inhereited classes", except in those rare instances [quoted text clipped - 5 lines] > inheritance is a complete red herring, because they're used for very > different purposes. Not a "complete" red herring--not a red herring at all. Just an observation. Use precise language Jon--that way we can communicate better, remember? ;-)
> Occasionally it's very handy to have access to private members in the > enclosing class, but *also* making a nested class gives an indication > of the context in which a class is relevant. > > Jon Your first reason I've already stated. Your second reason is very lame IMO--you can communicate much better using a comment-- /// in XML format.
Bottom line is that I doubt I use nested classes much more, any more than I use Enums for example (int enums, since byte enums are handy as flags). What completely confused me with nested classes is that I did not realize they are instantiated just like any two independent classes--or a composite class (Class A having as a member a class B)-- I assumed nested classes were like base class inherietance--big mistake.
RL
Peter Duniho - 22 Sep 2007 09:19 GMT >> Nested classes are useful in a number of situations, and are no more >> "painful" than normal classes. Comparing them to composition and >> inheritance is a complete red herring, because they're used for very >> different purposes. > > Not a "complete" red herring--not a red herring at all. No. "Complete" is definitely the qualifier needed here.
Nested classes are not at all like composition or inheritance, nor are they used for the same sort of reasons. Any comparison of nested classes to composition or inheritance is very much a red herring.
> Just an observation. It's an incorrect observation. And personally, I think it odd that you would consider those language features somehow related, given what you wrote at the end of your post (see below).
> [...] > Your first reason I've already stated. Your second reason is very > lame IMO--you can communicate much better using a comment-- /// in XML > format. Ahh, yes. Let's abandon language features and structure OOP design altogether. After all, we can simply document all relationships between all of the code and all of the data just by putting in comments.
Um, no. As I stated before, the access aspect of nested classes is a relatively minor part of the usefulness of nested classes. They would be nearly as useful even without that.
> Bottom line is that I doubt I use nested classes much more, any more > than I use Enums for example (int enums, since byte enums are handy as [quoted text clipped - 3 lines] > I assumed nested classes were like base class inherietance--big > mistake. If you understand now that nested classes are nothing like class inheritance, why is it that you continue to insist that compositing and inheritance are "better"? How can it be "better"? As you've already noted, nested classes do something completely different from compositing and inheritance.
Saying that inheritance is better than nested classes is like me saying that my pencil is better than my toothbrush. Neither is "better" than the other; they are used for completely different purposes.
Pete
raylopez99 - 22 Sep 2007 10:29 GMT > If you understand now that nested classes are nothing like class > inheritance, why is it that you continue to insist that compositing and > inheritance are "better"? How can it be "better"? As you've already > noted, nested classes do something completely different from compositing > and inheritance. Yes, indeed. I thought nested classes were like a sort of class access modifier, and worked similar to inhereitance. But they are simply a mechanism to defeat information hiding of private members in the enclosing class--a step backwards IMO from encapsulation.
> Saying that inheritance is better than nested classes is like me saying > that my pencil is better than my toothbrush. Neither is "better" than > the other; they are used for completely different purposes. But if you're a writer, a pencil *is* better than a toothbrush. And for this reason inhereitance and composition *is* better than nested classes. The former are the bread and butter of OOP.
My last post in this thread; thanks for your help.
RL
Peter Duniho - 22 Sep 2007 18:56 GMT > Yes, indeed. I thought nested classes were like a sort of class > access modifier, and worked similar to inhereitance. And as you see, they are neither.
> But they are > simply a mechanism to defeat information hiding of private members in > the enclosing class That is just not true. Nested classes do NOT exist as "simply a mechanism to defeat information hiding". The access to the containing class is only a natural side-effect of the consistent design of nested classes. Since a nested class is by definition a _part_ of the containing class, then just as every other member that is a part of the containing class has access to private members, so too does the nested class.
In my opinion, this is a very natural and clean design. However, regardless of what you think about that aspect of the design, it is just silly to claim that nested classes exist solely for that purpose. As I have said repeatedly, nested classes would be nearly as useful even without access to the containing class's members.
> [...] > But if you're a writer, a pencil *is* better than a toothbrush. What an absurd statement to make. If you had written "if you are writing", you might have had a true statement. But that statement would have solidly reinforced my point, since as I've said, nested classes are relevant to a specific purpose, so of course they are "better" for a specific purpose than something not intended for that purpose.
It's true that inheritance is a "better" solution for addressing the OOP technique of inheriting functionality than are nested classes. But that's only because nested classes don't have anything to do with inheriting functionality. You could just as correctly say that nested classes are a "better" solution for addressing the OOP technique of encapsulating data structures than is inheritance.
But that doesn't mean that either technique is actually literally better than the other. It just means that you use the technique designed for a specific goal when trying to achieve that goal.
By writing "if you're a writer", you've made a completely silly statement. Writers have just as much use for a toothbrush as they do for a pencil. They don't use the toothbrush for writing (one hopes), but they still need to brush their teeth.
That is, in fact, the point of my analogy.
> And > for this reason inhereitance and composition *is* better than nested > classes. The former are the bread and butter of OOP. And nested classes are too. They just address different issues than do inheritance and composition. Since nested classes are for a completely different purpose, they are neither "better" nor "worse" than inheritance and composition. They are simply _different_.
> My last post in this thread; You've said that before. :)
> thanks for your help. You're welcome.
Pete
Jon Skeet [C# MVP] - 22 Sep 2007 19:25 GMT <snip>
> By writing "if you're a writer", you've made a completely silly > statement. Writers have just as much use for a toothbrush as they do > for a pencil. They don't use the toothbrush for writing (one hopes), > but they still need to brush their teeth. Ironically, although I'm a writer I use a toothbrush twice a day, but I can't remember when I last used a pencil :)
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Michael S - 25 Sep 2007 13:22 GMT > Ironically, although I'm a writer I use a toothbrush twice a day, but I > can't remember when I last used a pencil :) ... you nerd... :)
- Michael Starberg
Doug Semler - 26 Sep 2007 01:36 GMT >> Ironically, although I'm a writer I use a toothbrush twice a day, but I >> can't remember when I last used a pencil :) > > ... you nerd... :) If he's anything like me...he'd probably prefer "geek" to "nerd" :-D
 Signature Doug Semler, MCPD a.a. #705, BAAWA. EAC Guardian of the Horn of the IPU (pbuhh). The answer is 42; DNRC o- Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?
Michael S - 26 Sep 2007 10:25 GMT > If he's anything like me...he'd probably prefer "geek" to "nerd" :-D Hehe, geeks uses pencils. :)
- Michael Starberg
Doug Semler - 27 Sep 2007 00:30 GMT >> If he's anything like me...he'd probably prefer "geek" to "nerd" :-D > > Hehe, geeks uses pencils. :) Noooo geeks use dry erase markers! :)
 Signature Doug Semler, MCPD a.a. #705, BAAWA. EAC Guardian of the Horn of the IPU (pbuhh). The answer is 42; DNRC o- Gur Hfrarg unf orpbzr fb shyy bs penc gurfr qnlf, abbar rira erpbtavmrf fvzcyr guvatf yvxr ebg13 nalzber. Fnq, vfa'g vg?
Michael S - 27 Sep 2007 10:17 GMT >>> If he's anything like me...he'd probably prefer "geek" to "nerd" :-D >> >> Hehe, geeks uses pencils. :) > > Noooo geeks use dry erase markers! :) I stand corrected :)
- Michael Starberg
Michael S - 25 Sep 2007 13:28 GMT Peter: I have now read this entire thread, and I admire your patience with this dude.
Also, I had never considered nested classes so much, even if I use them often. I got all you said, the first time you explained it. Actually, it worked as one might expect.
raylopes99: Next time you try to learn something in .NET, don't start by snorting a full kilogram of amphetamines, make up how things should work according to you, and then refuse to stand corrected.
Amusing Thread :) - Michael Starberg
Smithers - 25 Sep 2007 18:40 GMT <snip>
> Peter: > I have now read this entire thread, > and I admire your patience with this dude. Totally agreed! - Jon and Peter should get some award for their routine contributions and patience in this NG. Jon is already an MVP - Peter should be too, IMO.
-S
Jon Skeet [C# MVP] - 22 Sep 2007 19:23 GMT > > > Bottom line: nested classes are a pain and "composite classes" are > > > better, as is "inhereited classes", except in those rare instances [quoted text clipped - 9 lines] > observation. Use precise language Jon--that way we can communicate > better, remember? ;-) No, it *is* a red herring - they're used for different purposes, so shouldn't be compared. It's like saying, "Inheritance is a pain, and method calls are better".
> > Occasionally it's very handy to have access to private members in the > > enclosing class, but *also* making a nested class gives an indication [quoted text clipped - 3 lines] > lame IMO--you can communicate much better using a comment-- /// in XML > format. There are advantages in making the class nested in terms of intellisense, however. Suppose you needed 5 classes in a namespace, each of which also needed 2 classes just for use with that one. 15 classes in total. Using top level classes, Intellisense would show you all 15 each time. Using nested classes, it's more obvious when reading the code (without needing to consult documentation) that the nested class is directly related to its enclosing class, and Intellisense will help you pick the right context - when you're not dealing with the enclosing class, the nested class won't be offered.
> Bottom line is that I doubt I use nested classes much more, any more > than I use Enums for example (int enums, since byte enums are handy as > flags). Nested classes are useful. Enums are useful. (Enums could be more useful if they had more of an OO feel, but I digress.) Neither should be abandoned, and neither is a "pain". The "problems" you've shown in this thread are problems with your understanding, *not* problems with nested classes themselves.
> What completely confused me with nested classes is that I did > not realize they are instantiated just like any two independent > classes--or a composite class (Class A having as a member a class B)-- > I assumed nested classes were like base class inherietance--big > mistake. Yes, that's a mistake. But having realised that mistake (and having had it pointed out to you) you should understand that they are *not* a pain. Anything can be a pain when you don't understand it.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
judah veichselfish - 13 Nov 2007 15:01 GMT Hi, You wrote: The "forward reference" isn't a way, because no such thing exists in C#. If forward reference does not exist in c#, why the compilation of following piece of code will fail? a=5; int a; Thanks in advance xyoavx
EggHeadCafe - .NET Developer Portal of Choice http://www.eggheadcafe.com
Jon Skeet [C# MVP] - 13 Nov 2007 15:18 GMT > If forward reference does not exist in c#, why the compilation of following piece of code will fail? > a=5; > int a; Forward references in the context of the discussion are to do with declaring that methods (or other members) exist in a class or similar "outer scope" before providing the implementation.
It's not to do with trying to use a *local variable* within a method before declaring it.
Jon
Jon Skeet [C# MVP] - 21 Sep 2007 07:51 GMT > > As Jon says, this has absolutely nothing to do with the concept of > > forward references in C++. C# doesn't even have the concept of forward [quoted text clipped - 3 lines] > > Call it what you want, call it macaroni. That's a *really* dangerous attitude. Ignoring standard terminology is a recipe for disaster - it's only through shared terminology that we can communicate.
> I'm a rapid coder, not a software engineer. That's an even more dangerous attitude - it smacks of not caring about doing things the most appropriate way or learning how things really work.
<snip>
> Yeah, nice, but there's no nested class in your example. This whole > thread is about nested classes. But I see what you're driving at I [quoted text clipped - 3 lines] > using access modifiers "protected" and "protected internal" for the > nested class. It's *not* a trivial point, as you were claiming that nested classes acted differently to normal classes in terms of needing your odd "nexus" idea.
> > In the first DisplayA() method, it uses the value from the object passed > > in. In the second DisplayA() method, it uses the value of the instance [quoted text clipped - 3 lines] > class nomenclature, as it surely will (see below), it creates the > disconnect that prompted my original post. Nope, there's no clash at all.
> > If you don't want to require an instance, that's easy: just make the > > method static. It has nothing to do with the access modifiers. It has > > everything to do with whether the method is an instance method or not. > > Actually I did make the method static in some code I haven't posted, > and I had so many compile errors I had to switch to non-static. You shouldn't change things between being static and non-static just to fix compilation errors. Things should be static if they logically belong to the type rather than any particular instance, and vice versa.
> Static creates huge problems in your code, for reasons too numerous to > mention, but one is that you cannot seem to inhereit static. Um, using static members doesn't create huge problems when there's a good reason for them being static. You just need to understand what it means.
> > Again, there's no such thing as a forward reference in C#. And if you > > wanted Outer1 to be able to access something in Nested1, the access [quoted text clipped - 4 lines] > classes Pete! For Pete's sake, who to believe? You or book? Book > sez eye. Did the book give any reasoning? If not, I would take it with a pinch of salt. I tend to make nested classes private and give them internal methods to access from the enclosing class.
> > > Thus speaketh Ray Lopez. So it is written, so it shall come to pass. > > [quoted text clipped - 8 lines] > I don't refuse answers, I make assertions and back them with > evidence. In this case you made assertions which were completely false though.
<snip>
> BTW, here is what I found in my latest version of the "nested class > problem" (one reason I've avoided using them--they're a pain). It doesn't show the "nested class problem" at all, because the errors you're showing would occur trying to reference a non-nested class too. (Some would be access errors rather than errors of "you can't use a field access as a statement on its own", but that's about it.)
Error CS0201 has nothing to do with nested classes.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|