?? 'new' and 'protected' Modifiers on Structs ??

T

Tom Baxter

Hi everyone,

Has anyone looked at section 18.1.1 of the C# spec? It indicates 'new' and
'protected' are valid modifiers on struct declarations. First, how can
'protected' be valid on a struct, since structs cannot be inherited? The
compiler gives an error (as I expect it should) if you try this:

protected struct MyStruct {}

so I'm wondering if the spec is wrong when it says 'protected' is a valid
struct-modifier.

The second point about section 18.1.1 is that it indicates 'new' is an
allowable modifier on a struct. Actually, 18.1.1 indicates, "The modifiers
of a struct declaration have the same meaning as those of a class
declaration", referring the reader to section 17.1.1 on class declaration
modifiers.

I looked at section 17.1.1 and sure enough, it says:

"The new modifier is permitted on nested classes.
It specifies that the class hides an inherited member
by the same name, as described in section 17.2.2. It
is a compile-time error for the new modifier to appear
on a class declaration that is not a nested class declaration."

My testing indicates 'new' is not allowed on class nor struct declarations
(nested or not). It seems this is how 'new' should be used as a class
modifier, according to the spec (sec. 17.1.1):

class MyClass {
public virtual int M() { return 1; }
}

class Outer {
new class Inner : MyClass { // ERROR on 'new' modifier
public new int M() { return 2; }
}
}

The above code gives a warning on the declaration of Inner.

So, am I way off base here? Is there something wrong with sections 18.1.1
and 17.1.1?

Thanks
 
J

John B

Tom said:
Hi everyone,

Has anyone looked at section 18.1.1 of the C# spec? It indicates 'new'
and 'protected' are valid modifiers on struct declarations. First, how
can 'protected' be valid on a struct, since structs cannot be inherited?
The compiler gives an error (as I expect it should) if you try this:

protected struct MyStruct {}

so I'm wondering if the spec is wrong when it says 'protected' is a
valid struct-modifier.

The second point about section 18.1.1 is that it indicates 'new' is an
allowable modifier on a struct. Actually, 18.1.1 indicates, "The
modifiers of a struct declaration have the same meaning as those of a
class declaration", referring the reader to section 17.1.1 on class
declaration modifiers.

I looked at section 17.1.1 and sure enough, it says:

"The new modifier is permitted on nested classes.
It specifies that the class hides an inherited member
by the same name, as described in section 17.2.2. It
is a compile-time error for the new modifier to appear
on a class declaration that is not a nested class declaration."

My testing indicates 'new' is not allowed on class nor struct
declarations (nested or not). It seems this is how 'new' should be used
as a class modifier, according to the spec (sec. 17.1.1):

class MyClass {
public virtual int M() { return 1; }
}

class Outer {
new class Inner : MyClass { // ERROR on 'new' modifier
public new int M() { return 2; }
}
}

The above code gives a warning on the declaration of Inner.
I think if you change your definition to actually hide a member (M) you
will remove that error.


class MyClass
{
public virtual int M() { return 1; }
}

class Outer : MyClass
{
public new class M : MyClass
{
}
}

class C2 : MyClass
{
public new struct M
{
}
}
 
M

Marc Gravell

And on the "protected" side - it again relates to things that subclass
the containing class - i.e.

public class BaseClass {
void TestBase() {
NestedStruct ns;
}
private struct NestedStruct { int a;}
}
public class SubClass : BaseClass {
void TestSub() {
NestedStruct ns; // **ERROR
}
}

The above is illegal, since SubClass cannot see BaseClass.NestedStruct
(since it is private); however, change NestedStruct to be protected,
and any sublasses of BaseClass can now see it.

Marc
 
T

Tom Baxter

Thanks, Marc!! I appeciate!


Marc Gravell said:
And on the "protected" side - it again relates to things that subclass
the containing class - i.e.

public class BaseClass {
void TestBase() {
NestedStruct ns;
}
private struct NestedStruct { int a;}
}
public class SubClass : BaseClass {
void TestSub() {
NestedStruct ns; // **ERROR
}
}

The above is illegal, since SubClass cannot see BaseClass.NestedStruct
(since it is private); however, change NestedStruct to be protected,
and any sublasses of BaseClass can now see it.

Marc
 
T

Tom Baxter

I guess I spoke too soon! :)

This will compile:

class A {
protected struct B {}
}


but this will not:

struct A {
protected struct B {}
}


So, why would it be the case that a nested struct can be protected if it's
within a class but not if it's within a struct??
 
J

Jon Skeet [C# MVP]

Tom Baxter said:
I guess I spoke too soon! :)

This will compile:

class A {
protected struct B {}
}


but this will not:

struct A {
protected struct B {}
}


So, why would it be the case that a nested struct can be protected if it's
within a class but not if it's within a struct??

Structs cannot contain protected members at all - because you can't
derive from a struct. The fact that the member itself is a struct is
just coincidental - you'll see the same behaviour if B is a variable or
a method.
 
M

Marc Gravell

You can't inherit from a struct - in particular, you can't inherit
from struct A; hence "protected" is meaningless. You would get similar
(actually just a warning, not an error) if you marked class A as
"sealed": new protected member declared in sealed class.

Marc
 
T

Tom Baxter

It turns outy that a struct *can* be marked as protected but only of its
immediate parent is a class. If its immediate parent is a struct, it cannot
be protected. So, this does not compile:

class A {
class B {
struct C {
protected struct Z { }
}
}
}

while this does:

struct A {
struct B {
class C {
protected struct Z { }
}
}
}



So, why would it be the case that a nested struct can be protected if it's
within a class but not if it's within a struct??
 
P

Peter Duniho

So, why would it be the case that a nested struct can be protected if
it's within a class but not if it's within a struct??

You are not focusing on the important part. Any class can be
inherited. So any declaration within a class may have the "protected"
access.

It doesn't matter where the class is. You can declare it in a struct
if you like, the rule still applies.

Class C can't be "protected", because it's a member of a struct.
Struct B can't be "protected" because it's a member of a struct. But
Struct Z is a member of a class. Thus, it can be "protected".

It's the same exact rule that applies to the general case that started
this thread. Nothing's different about this most recent example.

Pete
 
T

Tom Baxter

How stupid of me! It's rather embarrassing, actually.

Thank you Jon, Marc and Pete. I sincerely appreciate you taking the time to
respond.

Jon, I am looking forward to your Manning book. Do you have a ballpark time
frame as to when it will be available in hard copy?
 
M

Marc Gravell

How stupid of me! It's rather embarrassing, actually.

Not at all; you weren't entirely sure of something, so you a: read the
spec, b: did some tests of your own to see how it behaved, and c:
asked relevant questions (with examples for illustartion) until it
"clicked". Sounds like a pretty sensible approach to me! Any other
questions, please ask away...

Marc
 
P

Peter Duniho

Not at all; you weren't entirely sure of something, so you a: read the
spec, b: did some tests of your own to see how it behaved, and c:
asked relevant questions (with examples for illustartion) until it
"clicked". Sounds like a pretty sensible approach to me! Any other
questions, please ask away...

Agreed. If only all questions posted here were approached by the
questioner so methodically and open-mindedly.

I'm always a little embarassed when I find out I read something wrong.
I suppose that's human nature. But in reality, as they say...the only
dumb question is the one you didn't ask. :) I never mind answering a
question posed by someone who is clearly sincere about the question,
and who is doing their best to present their question in an effective
way, as was the case here.

Pete
 
J

Jon Skeet [C# MVP]

Tom Baxter said:
How stupid of me! It's rather embarrassing, actually.

Thank you Jon, Marc and Pete. I sincerely appreciate you taking the time to
respond.

Jon, I am looking forward to your Manning book. Do you have a ballpark time
frame as to when it will be available in hard copy?

March 2008 - Amazon claims the middle of March, but I suspect it'll be
the end of March instead. No doubt it will partly depend on how
speedily the last phases (indexing, proof reading etc) go.

Nice to know you're looking forward to it though :)
 
J

Jon Skeet [C# MVP]

Marc Gravell said:
Not at all; you weren't entirely sure of something, so you a: read the
spec, b: did some tests of your own to see how it behaved, and c:
asked relevant questions (with examples for illustartion) until it
"clicked". Sounds like a pretty sensible approach to me! Any other
questions, please ask away...

Absolutely. Frankly, anyone who asks a question referring to the spec
is streets ahead of the game in my view :)
 

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