Enum "Inheritance"?

Nick Sabalausky a at a.a
Wed Feb 23 15:41:48 PST 2011


"%u" <wfunction at hotmail.com> wrote in message 
news:ik432q$29qu$1 at digitalmars.com...
>I have a question on enum "inheritance" -- I'm wondering if what's 
>happening below is a bug or by
> design?
>
> I have code like this:
>
> enum AccessMask { GenericRead = 0x80000000 }
> enum FileAccess : AccessMask { ReadData = 1 } //Errors
> void foo(FileAccess a) { /*Do something*/ }
> void bar() { foo(AccessMask.GenericRead); } //Errors
>
> I get two errors:
>
> 1. Inside FileAccess, I get an error with the assignment, telling me that 
> it can't work implicitly.
> If instead of "ReadData = 1" I write "ReadData = cast(AccessMask)1", it 
> works fine, but it's a pain.
>
> 2. bar() doesn't compile, because it's passing a less specialized value to 
> a more specialized one.
> While I understand why this wouldn't work from an actual _object_ 
> inheritance perspective, I don't
> see why this doesn't work in the case of enums -- after all, isn't the 
> subclass supposed to contain
> every member member of the superclass? Is this by design, and is there a 
> neat solution?
>

You're misunderstanding the way enum works. The "enum A : B {}" isn't 
inheritence, even though the syntax is similar to class inheritence. The 
part after the ":" is not a parent type, but the underlying representational 
type.

Ie:

enum IntBased { ValueA = 1; }
enum IntBased : int { ValueA = 1; } // Same as above
enum CharBased : char {ValueA = 'x'; }
enum StringBased : string {ValueA = "hello"; } // Not sure if this actually 
works
enum DoubleBased : double {ValueA = 3.14; }
// Etc...

The part after ":" just specifies what type each value is internally stored 
as. So when you say:

enum AccessMask { GenericRead = 0x80000000 }
enum FileAccess : AccessMask { ... }

...you've just told the compiler that each value of FileAccess is supposed 
to resolve to an AccessMask, not an int. But then you told it that 
FileAccess.ReadData is supposed to be 1, but that's impossible because 1 
isn't an AccessMask, it's an int. And not only that, but it's an int that 
doesn't even exist in AccessMask (which is why you need that cast. Although, 
all that your cast is doing is forcefully creating a completely invalid 
AccessMask).

What you need to do is something like:

enum AccessMask { GenericRead = 0x80000000 }
enum FileAccess : AccessMask { ReadData = AccessMask.GenericRead }

or:

enum AccessMask { GenericRead = 0x80000000, ReadData = 1 }
enum FileAccess : AccessMask { AccessMask.ReadData = 1 }



If neither of those are what you're after, then "enum FileAccess : 
AccessMask" isn't appropriate for the task anyway.





More information about the Digitalmars-d mailing list