By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,689 Members | 1,106 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,689 IT Pros & Developers. It's quick & easy.

passing enum value as an argument

P: n/a
I'm writing a class with a method that will accept 1 of 3 items listed in an
enum. Is it possible to pass the item name without the enum name in your
calling statement?

EXAMPLE:

public enum EnumName
FirstValue = 1
SecondValue = 2
ThirdValue = 3
end enum

CURRENTLY DOING THIS:
ObjectName.MethodName(EnumName.FirstValue)

WANT TO DO THIS:
ObjectName.MethodName(FirstValue)

Jul 22 '05 #1
Share this Question
Share on Google+
20 Replies


P: n/a
You can add an imports statement to the top of your code that imports
the enum.

Imports RootNamespace.MyEnum

Public Enum MyEnum As Integer
FirstValue = 1
SecondValue = 2
ThirdValue = 3
End Enum

Jul 22 '05 #2

P: n/a
=?Utf-8?B?R2xlbm4gVmVuemtl?= <Gl*********@discussions.microsoft.com>
wrote in news:39**********************************@microsof t.com:
CURRENTLY DOING THIS:
ObjectName.MethodName(EnumName.FirstValue)

WANT TO DO THIS:
ObjectName.MethodName(FirstValue)


No - its part of its "namespace" if you will and prevent conflicts or requiring prefixes on each
enum value. Why would you want to do this?
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Empower ASP.NET with IntraWeb
http://www.atozed.com/IntraWeb/
Jul 22 '05 #3

P: n/a

Hi there,

That would defeat the purpose of having an Enum. you might as well create
three variables then.

--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Glenn Venzke" wrote:
I'm writing a class with a method that will accept 1 of 3 items listed in an
enum. Is it possible to pass the item name without the enum name in your
calling statement?

EXAMPLE:

public enum EnumName
FirstValue = 1
SecondValue = 2
ThirdValue = 3
end enum

CURRENTLY DOING THIS:
ObjectName.MethodName(EnumName.FirstValue)

WANT TO DO THIS:
ObjectName.MethodName(FirstValue)

Jul 22 '05 #4

P: n/a
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
That would defeat the purpose of having an Enum. you might as well create
three variables then.


I don't see how it would defeat type safety, which is the purpose of
having an enum from my point of view. So long as you couldn't pass in a
value from a *different* enum, it would be fine. I don't see any reason
why the language couldn't allow it.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 22 '05 #5

P: n/a
The value of an Enum option evaluates to a constant, so technically, I COULD
pass a value from another Enum, so long as Option Strict is OFF and even if
it was on, I could cast it to the Enum. The only useful things in my opinion
about Enums is that they they help you code fast (intellisense), you dont
have to remember what each value represents and it provides a range of
acceptable values. I don't really see any type safety benefits.

Anyways, If the language allowed you to reference it directly, then you
would have ambiguity problems with variables declared in the same scope and
therefore WOULD defeat the purpose of having an Enum in the first place.

From MSDN:

------------------------------------------

Enumeration variables are variables declared to be of an Enum type.
Declaring a variable in this way helps you to control the values you assign
to it. If Option Strict is On, you can assign only enumeration members to the
enumeration variable. In this case, you can use the CType keyword to
explicitly convert a numeric data type to an Enum type.

You must qualify every reference to an enumeration member, either with the
name of an enumeration variable or with the enumeration name itself. For
example, in the preceding example, you can refer to the first member as
SecurityLevel.IllegalEntry, but not as IllegalEntry.

------------------------------------------

Good luck!
--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Jon Skeet [C# MVP]" wrote:
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
That would defeat the purpose of having an Enum. you might as well create
three variables then.


I don't see how it would defeat type safety, which is the purpose of
having an enum from my point of view. So long as you couldn't pass in a
value from a *different* enum, it would be fine. I don't see any reason
why the language couldn't allow it.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 22 '05 #6

P: n/a
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
The value of an Enum option evaluates to a constant, so technically, I COULD
pass a value from another Enum, so long as Option Strict is OFF and even if
it was on, I could cast it to the Enum.
Yes, if you want to get around the type safety, you can. I don't see
how that makes it less valuable to have enums which can be safely
passed around if you *don't* deliberately break things, nor would
inferring the type from the method parameter break that type safety.
The only useful things in my opinion about Enums is that they they
help you code fast (intellisense), you dont have to remember what
each value represents and it provides a range of acceptable values. I
don't really see any type safety benefits.
Try getting the values of FileAccess, FileMode, FileShare etc the wrong
way round on a call to the FileStream constructor. The compiler tells
you - so long as you haven't *deliberately* started casting from one
enum type to another via their underlying type. If you do that, you're
clearly asking for trouble (just like if you turn option strict off) -
but I rather like the fact that I get an error when I've *mistakenly*
got the parameters the wrong way round.
Anyways, If the language allowed you to reference it directly, then you
would have ambiguity problems with variables declared in the same scope and
therefore WOULD defeat the purpose of having an Enum in the first place.


You would only have ambiguity problems if you'd got another
member/variable/whatever with the same name. At that point, the
compiler could force you do disambiguate. What's the problem?

(Quoting what the language specification says *now* doesn't stop the
language changing - C# is doing exactly that when it comes to
delegates, where the delegate type is inferred in v2.0 despite it not
being inferred in the currently released version.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 22 '05 #7

P: n/a
That is exactly the point. I encourage Enums. Going back to the question, the
user is trying to use them without fully qualifying them which in turn
results in "defeat of the purpose" like I mentioned before.
--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Jon Skeet [C# MVP]" wrote:
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
The value of an Enum option evaluates to a constant, so technically, I COULD
pass a value from another Enum, so long as Option Strict is OFF and even if
it was on, I could cast it to the Enum.


Yes, if you want to get around the type safety, you can. I don't see
how that makes it less valuable to have enums which can be safely
passed around if you *don't* deliberately break things, nor would
inferring the type from the method parameter break that type safety.
The only useful things in my opinion about Enums is that they they
help you code fast (intellisense), you dont have to remember what
each value represents and it provides a range of acceptable values. I
don't really see any type safety benefits.


Try getting the values of FileAccess, FileMode, FileShare etc the wrong
way round on a call to the FileStream constructor. The compiler tells
you - so long as you haven't *deliberately* started casting from one
enum type to another via their underlying type. If you do that, you're
clearly asking for trouble (just like if you turn option strict off) -
but I rather like the fact that I get an error when I've *mistakenly*
got the parameters the wrong way round.
Anyways, If the language allowed you to reference it directly, then you
would have ambiguity problems with variables declared in the same scope and
therefore WOULD defeat the purpose of having an Enum in the first place.


You would only have ambiguity problems if you'd got another
member/variable/whatever with the same name. At that point, the
compiler could force you do disambiguate. What's the problem?

(Quoting what the language specification says *now* doesn't stop the
language changing - C# is doing exactly that when it comes to
delegates, where the delegate type is inferred in v2.0 despite it not
being inferred in the currently released version.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 22 '05 #8

P: n/a
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
That is exactly the point. I encourage Enums. Going back to the question, the
user is trying to use them without fully qualifying them which in turn
results in "defeat of the purpose" like I mentioned before.


But it *doesn't* defeat the purpose. It doesn't stop the compiler from
noticing if he's trying to pass in a value which isn't in the enum. It
doesn't stop the compiler from noticing if he's trying to pass in a
value from another enum, whether explicitly or not.

If you had two enums, FirstEnum with values Foo, Bar, Baz and
SecondEnum with values Fred, George, Harry, and two methods:

TakeFirstEnum (FirstEnum x)
TakeSecondEnum (SecondEnum y)

then the following would be valid calls:
TakeFirstEnum(Foo)
TakeFirstEnum(FirstEnum.Foo)
TakeSecondEnum(Fred)
TakeSecondEnum(SecondEnum.Fred)
and the following would be invalid calls:
TakeFirstEnum(Fred)
TakeFirstEnum(SecondEnum.Fred)
TakeSecondEnum(Foo)
TakeSecondEnum(FirstEnum.Foo)

So there's still just as much type safety there as there was before -
which would *not* be the case if he'd just gone with ints rather than
enums in the first place. For that reason, I fail to see how it defeats
the purpose.

The only times it would cause potential for confusion would be where
there was an overloaded method where the differing parameter types were
both enums. In that case, the compiler could force the developer to
explicitly state which enum he wanted to use.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 22 '05 #9

P: n/a
I am not sure what language you are coding in, but at least in VB.NET you are
incorrect. Here are the TRUE results:

TakeFirstEnum(Foo) --> FAILS
TakeFirstEnum(FirstEnum.Foo) --> SUCCEEDS
TakeSecondEnum(Fred) --> FAILS
TakeSecondEnum(SecondEnum.Fred) --> SUCCEEDS

TakeFirstEnum(Fred) --> FAILS
TakeFirstEnum(SecondEnum.Fred) --> SUCCEEDS
TakeSecondEnum(Foo) --> FAILS
TakeSecondEnum(FirstEnum.Foo) --> SUCCEEDS

Like I said before, ultimately, the enum evaluates to a constant, so there
is really no "type safety" here, except for the type of the constant and the
range of valid values the enum provides. Because of this, I could call the
first function with a value from the second Enum so long as it evaluates to a
value within the range of the first Enum. What I cannot do however is call
one of the values of the Enum without fully qualifying it because once again,
like I said before) you would run into ambiguity problems.

It may not be the case in the language you are using, but it certainly is
the case with VB.NET. Try it, you will see.

--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Jon Skeet [C# MVP]" wrote:
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
That is exactly the point. I encourage Enums. Going back to the question, the
user is trying to use them without fully qualifying them which in turn
results in "defeat of the purpose" like I mentioned before.


But it *doesn't* defeat the purpose. It doesn't stop the compiler from
noticing if he's trying to pass in a value which isn't in the enum. It
doesn't stop the compiler from noticing if he's trying to pass in a
value from another enum, whether explicitly or not.

If you had two enums, FirstEnum with values Foo, Bar, Baz and
SecondEnum with values Fred, George, Harry, and two methods:

TakeFirstEnum (FirstEnum x)
TakeSecondEnum (SecondEnum y)

then the following would be valid calls:
TakeFirstEnum(Foo)
TakeFirstEnum(FirstEnum.Foo)
TakeSecondEnum(Fred)
TakeSecondEnum(SecondEnum.Fred)
and the following would be invalid calls:
TakeFirstEnum(Fred)
TakeFirstEnum(SecondEnum.Fred)
TakeSecondEnum(Foo)
TakeSecondEnum(FirstEnum.Foo)

So there's still just as much type safety there as there was before -
which would *not* be the case if he'd just gone with ints rather than
enums in the first place. For that reason, I fail to see how it defeats
the purpose.

The only times it would cause potential for confusion would be where
there was an overloaded method where the differing parameter types were
both enums. In that case, the compiler could force the developer to
explicitly state which enum he wanted to use.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 22 '05 #10

P: n/a
Madestro,
|I am not sure what language you are coding in, but at least in VB.NET you
are
| incorrect. Here are the TRUE results:

| Like I said before, ultimately, the enum evaluates to a constant, so there
| is really no "type safety" here

Your statement is True, if and only if, you are using Option Strict Off.

If you use Option Strict On, than Enums are type safe as Jon suggests.

I normally use Option Strict On to ensure type safety, by having compile
time errors, rather then hard to find runtime time errors as your sample
potentially is.

Remember that Option Strict Off is the default and it allows (potentially
dangerous) implicit casts, such as your example of the SecondEnum value to a
FirstEnum type.

| It may not be the case in the language you are using, but it certainly is
| the case with VB.NET. Try it, you will see.
Try your example with Option Strict On...

Hope this helps
Jay

"Madestro" <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote in message
news:BA**********************************@microsof t.com...
|I am not sure what language you are coding in, but at least in VB.NET you
are
| incorrect. Here are the TRUE results:
|
| TakeFirstEnum(Foo) --> FAILS
| TakeFirstEnum(FirstEnum.Foo) --> SUCCEEDS
| TakeSecondEnum(Fred) --> FAILS
| TakeSecondEnum(SecondEnum.Fred) --> SUCCEEDS
|
| TakeFirstEnum(Fred) --> FAILS
| TakeFirstEnum(SecondEnum.Fred) --> SUCCEEDS
| TakeSecondEnum(Foo) --> FAILS
| TakeSecondEnum(FirstEnum.Foo) --> SUCCEEDS
|
| Like I said before, ultimately, the enum evaluates to a constant, so there
| is really no "type safety" here, except for the type of the constant and
the
| range of valid values the enum provides. Because of this, I could call the
| first function with a value from the second Enum so long as it evaluates
to a
| value within the range of the first Enum. What I cannot do however is call
| one of the values of the Enum without fully qualifying it because once
again,
| like I said before) you would run into ambiguity problems.
|
| It may not be the case in the language you are using, but it certainly is
| the case with VB.NET. Try it, you will see.
|
| --
| Juan Romero
| -----------------------------------------
| The successful person has the habit of doing the things failures don't
like
| to do.
| E.M. Gray
|
|
| "Jon Skeet [C# MVP]" wrote:
|
| > Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
| > > That is exactly the point. I encourage Enums. Going back to the
question, the
| > > user is trying to use them without fully qualifying them which in turn
| > > results in "defeat of the purpose" like I mentioned before.
| >
| > But it *doesn't* defeat the purpose. It doesn't stop the compiler from
| > noticing if he's trying to pass in a value which isn't in the enum. It
| > doesn't stop the compiler from noticing if he's trying to pass in a
| > value from another enum, whether explicitly or not.
| >
| > If you had two enums, FirstEnum with values Foo, Bar, Baz and
| > SecondEnum with values Fred, George, Harry, and two methods:
| >
| > TakeFirstEnum (FirstEnum x)
| > TakeSecondEnum (SecondEnum y)
| >
| > then the following would be valid calls:
| > TakeFirstEnum(Foo)
| > TakeFirstEnum(FirstEnum.Foo)
| > TakeSecondEnum(Fred)
| > TakeSecondEnum(SecondEnum.Fred)
| >
| >
| > and the following would be invalid calls:
| > TakeFirstEnum(Fred)
| > TakeFirstEnum(SecondEnum.Fred)
| > TakeSecondEnum(Foo)
| > TakeSecondEnum(FirstEnum.Foo)
| >
| > So there's still just as much type safety there as there was before -
| > which would *not* be the case if he'd just gone with ints rather than
| > enums in the first place. For that reason, I fail to see how it defeats
| > the purpose.
| >
| > The only times it would cause potential for confusion would be where
| > there was an overloaded method where the differing parameter types were
| > both enums. In that case, the compiler could force the developer to
| > explicitly state which enum he wanted to use.
| >
| > --
| > Jon Skeet - <sk***@pobox.com>
| > http://www.pobox.com/~skeet
| > If replying to the group, please do not mail me too
| >
Jul 22 '05 #11

P: n/a

Well, if you read the thread carefully you will see that I DID mention
Option Strict before. But even with Option Strict ON you can still pass a
value from another Enum if you cast it.

Nevertheless, because of all these comments, we are drifting away from the
point of this question, and I still stand on my ground: Refering to Enum
options without fully qualifying them defeats the purpose of having an Enum.
You might as well declare variables or constants if you dont want to go
through the trouble of qualifying names.

Cya!

--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Jay B. Harlow [MVP - Outlook]" wrote:
Madestro,
|I am not sure what language you are coding in, but at least in VB.NET you
are
| incorrect. Here are the TRUE results:

| Like I said before, ultimately, the enum evaluates to a constant, so there
| is really no "type safety" here

Your statement is True, if and only if, you are using Option Strict Off.

If you use Option Strict On, than Enums are type safe as Jon suggests.

I normally use Option Strict On to ensure type safety, by having compile
time errors, rather then hard to find runtime time errors as your sample
potentially is.

Remember that Option Strict Off is the default and it allows (potentially
dangerous) implicit casts, such as your example of the SecondEnum value to a
FirstEnum type.

| It may not be the case in the language you are using, but it certainly is
| the case with VB.NET. Try it, you will see.
Try your example with Option Strict On...

Hope this helps
Jay

"Madestro" <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote in message
news:BA**********************************@microsof t.com...
|I am not sure what language you are coding in, but at least in VB.NET you
are
| incorrect. Here are the TRUE results:
|
| TakeFirstEnum(Foo) --> FAILS
| TakeFirstEnum(FirstEnum.Foo) --> SUCCEEDS
| TakeSecondEnum(Fred) --> FAILS
| TakeSecondEnum(SecondEnum.Fred) --> SUCCEEDS
|
| TakeFirstEnum(Fred) --> FAILS
| TakeFirstEnum(SecondEnum.Fred) --> SUCCEEDS
| TakeSecondEnum(Foo) --> FAILS
| TakeSecondEnum(FirstEnum.Foo) --> SUCCEEDS
|
| Like I said before, ultimately, the enum evaluates to a constant, so there
| is really no "type safety" here, except for the type of the constant and
the
| range of valid values the enum provides. Because of this, I could call the
| first function with a value from the second Enum so long as it evaluates
to a
| value within the range of the first Enum. What I cannot do however is call
| one of the values of the Enum without fully qualifying it because once
again,
| like I said before) you would run into ambiguity problems.
|
| It may not be the case in the language you are using, but it certainly is
| the case with VB.NET. Try it, you will see.
|
| --
| Juan Romero
| -----------------------------------------
| The successful person has the habit of doing the things failures don't
like
| to do.
| E.M. Gray
|
|
| "Jon Skeet [C# MVP]" wrote:
|
| > Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
| > > That is exactly the point. I encourage Enums. Going back to the
question, the
| > > user is trying to use them without fully qualifying them which in turn
| > > results in "defeat of the purpose" like I mentioned before.
| >
| > But it *doesn't* defeat the purpose. It doesn't stop the compiler from
| > noticing if he's trying to pass in a value which isn't in the enum. It
| > doesn't stop the compiler from noticing if he's trying to pass in a
| > value from another enum, whether explicitly or not.
| >
| > If you had two enums, FirstEnum with values Foo, Bar, Baz and
| > SecondEnum with values Fred, George, Harry, and two methods:
| >
| > TakeFirstEnum (FirstEnum x)
| > TakeSecondEnum (SecondEnum y)
| >
| > then the following would be valid calls:
| > TakeFirstEnum(Foo)
| > TakeFirstEnum(FirstEnum.Foo)
| > TakeSecondEnum(Fred)
| > TakeSecondEnum(SecondEnum.Fred)
| >
| >
| > and the following would be invalid calls:
| > TakeFirstEnum(Fred)
| > TakeFirstEnum(SecondEnum.Fred)
| > TakeSecondEnum(Foo)
| > TakeSecondEnum(FirstEnum.Foo)
| >
| > So there's still just as much type safety there as there was before -
| > which would *not* be the case if he'd just gone with ints rather than
| > enums in the first place. For that reason, I fail to see how it defeats
| > the purpose.
| >
| > The only times it would cause potential for confusion would be where
| > there was an overloaded method where the differing parameter types were
| > both enums. In that case, the compiler could force the developer to
| > explicitly state which enum he wanted to use.
| >
| > --
| > Jon Skeet - <sk***@pobox.com>
| > http://www.pobox.com/~skeet
| > If replying to the group, please do not mail me too
| >

Jul 22 '05 #12

P: n/a
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
I am not sure what language you are coding in
C#.
but at least in VB.NET you are incorrect.
Not with option strict on. If you're programming with option strict
off, that's a different matter - you've given up any vestige of compile
time type safety already.
Here are the TRUE results:

TakeFirstEnum(Foo) --> FAILS
TakeFirstEnum(FirstEnum.Foo) --> SUCCEEDS
TakeSecondEnum(Fred) --> FAILS
TakeSecondEnum(SecondEnum.Fred) --> SUCCEEDS

TakeFirstEnum(Fred) --> FAILS
TakeFirstEnum(SecondEnum.Fred) --> SUCCEEDS
TakeSecondEnum(Foo) --> FAILS
TakeSecondEnum(FirstEnum.Foo) --> SUCCEEDS
The failures are all because the language doesn't allow what's being
proposed, of course.

However, I don't get the same results as you. Here's a short but
complete program to demonstrate:

Option Strict On

Imports System

Public Enum FirstEnum
Foo
Bar
Baz
End Enum

Public Enum SecondEnum
Fred
George
Harry
End Enum
Public Class Test

Shared Sub TakeFirstEnum (value As FirstEnum)
Console.WriteLine (value)
End Sub

Shared Sub TakeSecondEnum (value As SecondEnum)
Console.WriteLine (value)
End Sub

Shared Sub Main()
TakeFirstEnum(FirstEnum.Foo)
TakeFirstEnum(SecondEnum.Fred)
TakeSecondEnum(FirstEnum.Foo)
TakeSecondEnum(SecondEnum.Fred)
End Sub
End Class

Compiling the above gives:
c:\test\Test.vb(30) : error BC30512: Option Strict On disallows
implicit conversions from 'SecondEnum' to 'FirstEnum'.

TakeFirstEnum(SecondEnum.Fred)
~~~~~~~~~~~~~~~
c:\test\Test.vb(31) : error BC30512: Option Strict On disallows
implicit conversions from 'FirstEnum' to 'SecondEnum'.

TakeSecondEnum(FirstEnum.Foo)
~~~~~~~~~~~~~

Turning option strict off, it compiles fine, but as I said, if you're
running with option strict off I have very little sympathy with any
type safety issues you may run into :)
Like I said before, ultimately, the enum evaluates to a constant
Of the appropriate type though - the type of the expression is known to
the compiler.
so there
is really no "type safety" here, except for the type of the constant and the
range of valid values the enum provides.
Actually, the range of valid values the enum provides *isn't* part of
the safety - you can cast any value from the underlying type.
Because of this, I could call the first function with a value from
the second Enum so long as it evaluates to a value within the range
of the first Enum.
That's *entirely* wrong. With option strict on you can't call it at
all, and with option strict you can call it whether it's in the range
or not.
What I cannot do however is call one of the values of the Enum
without fully qualifying it because once again, like I said before)
you would run into ambiguity problems.
Well, you can't do it at the moment because the language specification
says you can't. There's nothing to stop the language specification from
changing to allow you to do it where there was no ambiguity - and that
change *wouldn't* lose the whole point of enums.
It may not be the case in the language you are using, but it certainly is
the case with VB.NET. Try it, you will see.


I tried it, and found what you asserted to be wrong - did you actually
try it, or were you making assumptions?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 22 '05 #13

P: n/a
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
Well, if you read the thread carefully you will see that I DID mention
Option Strict before.
Yes, but then you made blanket statements which didn't state that you
were essentially working in a non-typesafe way. You can't expect type
safety at all (at compile time) when you've got option strict turned
off. Do you actually write much code without option strict on?
But even with Option Strict ON you can still pass a
value from another Enum if you cast it.
Yes, if you cast it. In what way does that diminish the usefulness of
having compile-time type safety when you're *not* deliberately trying
to break things?
Nevertheless, because of all these comments, we are drifting away from the
point of this question, and I still stand on my ground: Refering to Enum
options without fully qualifying them defeats the purpose of having an Enum.
You seem to think that the sole purpose of enums is to force the
developer into fully qualifying names. I think that's a pretty narrow
idea of the purpose - for me, it's mostly to provide a typesafe way of
having a collection of values which map to primitive values.

By your idea of the purpose of enums, yes, the OP's solution would
indeed defeat the purpose. I think you'll find you're in the minority
when it comes to that idea.
You might as well declare variables or constants if you dont want to go
through the trouble of qualifying names.


Except then you lose the type safety, and could accidentally end up
using (say) an HTTP response code where you should actually be using a
file share mode.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 22 '05 #14

P: n/a
Once again, please read the posts above. I did talk about Option Strict.

I clearly stated that you could CAST to the Enum type. Obviously IMPLICIT
conversions will yield an error with Option Strict ON, that is the whole
point of it.

As for the evaluation at runtime, because the compiler knows the type, a
constant or variable would provide THE SAME level of type safety.

The range of values IS part of the safety. If you don't believe me, read the
documentation and/or attempt to assign an integer outside of the range and
you will see what happens. E.g.:

Enum Juan
Zero 'By default this is initialized to 0
One 'By default this is initialized to 1
Two 'By default this is initialized to 2
End Enum

Public sub New()
Test(2) ------------> Option Strict OFF, this will be OK
Test(3) ------------> Option Strict OFF, this will FAIL
Test(ctype(2,Juan)) ------------> Option Strict ON, This will be OK
Test(ctype(3,Juan)) -------------> Option Strict ON, this will FAIL
End Sub

Public Function Test(ByVal e as JuanEnum)

End Function

As you can see I am not *entirely* wrong. Try creating another Enum and pass
it to the function (with casting if using Option Strict ON) and you will see
that the value is accepted so long as it is in the range of the enum.

As far as ambiguity, a language can NEVER allow you to use the name
directly. Consider the following scenario:

Public Class One
Dim Juan as integer = 0
Enum Sample
Juan = 1
Javier = 2
End Enum
Public Sub New()
console.writeline(Juan) --------> * This will print "1"
End Sub
End Class

How will the compiler resolve this variable?
Answer: 1 . It needs the fully qualified name of the variable in order to
know you want the Enum and not the local variable. How can you possible have
two variables with the same name in the same scope?

Finally, I never post anything until I try it myself.

Thank you!
--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Jon Skeet [C# MVP]" wrote:
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
I am not sure what language you are coding in


C#.
but at least in VB.NET you are incorrect.


Not with option strict on. If you're programming with option strict
off, that's a different matter - you've given up any vestige of compile
time type safety already.
Here are the TRUE results:

TakeFirstEnum(Foo) --> FAILS
TakeFirstEnum(FirstEnum.Foo) --> SUCCEEDS
TakeSecondEnum(Fred) --> FAILS
TakeSecondEnum(SecondEnum.Fred) --> SUCCEEDS

TakeFirstEnum(Fred) --> FAILS
TakeFirstEnum(SecondEnum.Fred) --> SUCCEEDS
TakeSecondEnum(Foo) --> FAILS
TakeSecondEnum(FirstEnum.Foo) --> SUCCEEDS


The failures are all because the language doesn't allow what's being
proposed, of course.

However, I don't get the same results as you. Here's a short but
complete program to demonstrate:

Option Strict On

Imports System

Public Enum FirstEnum
Foo
Bar
Baz
End Enum

Public Enum SecondEnum
Fred
George
Harry
End Enum
Public Class Test

Shared Sub TakeFirstEnum (value As FirstEnum)
Console.WriteLine (value)
End Sub

Shared Sub TakeSecondEnum (value As SecondEnum)
Console.WriteLine (value)
End Sub

Shared Sub Main()
TakeFirstEnum(FirstEnum.Foo)
TakeFirstEnum(SecondEnum.Fred)
TakeSecondEnum(FirstEnum.Foo)
TakeSecondEnum(SecondEnum.Fred)
End Sub
End Class

Compiling the above gives:
c:\test\Test.vb(30) : error BC30512: Option Strict On disallows
implicit conversions from 'SecondEnum' to 'FirstEnum'.

TakeFirstEnum(SecondEnum.Fred)
~~~~~~~~~~~~~~~
c:\test\Test.vb(31) : error BC30512: Option Strict On disallows
implicit conversions from 'FirstEnum' to 'SecondEnum'.

TakeSecondEnum(FirstEnum.Foo)
~~~~~~~~~~~~~

Turning option strict off, it compiles fine, but as I said, if you're
running with option strict off I have very little sympathy with any
type safety issues you may run into :)
Like I said before, ultimately, the enum evaluates to a constant


Of the appropriate type though - the type of the expression is known to
the compiler.
so there
is really no "type safety" here, except for the type of the constant and the
range of valid values the enum provides.


Actually, the range of valid values the enum provides *isn't* part of
the safety - you can cast any value from the underlying type.
Because of this, I could call the first function with a value from
the second Enum so long as it evaluates to a value within the range
of the first Enum.


That's *entirely* wrong. With option strict on you can't call it at
all, and with option strict you can call it whether it's in the range
or not.
What I cannot do however is call one of the values of the Enum
without fully qualifying it because once again, like I said before)
you would run into ambiguity problems.


Well, you can't do it at the moment because the language specification
says you can't. There's nothing to stop the language specification from
changing to allow you to do it where there was no ambiguity - and that
change *wouldn't* lose the whole point of enums.
It may not be the case in the language you are using, but it certainly is
the case with VB.NET. Try it, you will see.


I tried it, and found what you asserted to be wrong - did you actually
try it, or were you making assumptions?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 22 '05 #15

P: n/a
> Yes, but then you made blanket statements which didn't state that you
were essentially working in a non-typesafe way. You can't expect type
safety at all (at compile time) when you've got option strict turned
off. Do you actually write much code without option strict on?
The issue at hand in this particular question is whether you could possibly
call a value from an Enum without qualifying the value, the discussion is not
about type safety. Anytime you assign a type of any kind to any variable you
get type safety, there is no argument there. It was the other reply that
introduced type safety into this thread. By the way, I ALWAYS code with
Option Strict ON.

Yes, if you cast it. In what way does that diminish the usefulness of having compile-time type safety when you're *not* deliberately trying
to break things?
Again. Not talking about type safety here.
You seem to think that the sole purpose of enums is to force the
developer into fully qualifying names. I think that's a pretty narrow
idea of the purpose - for me, it's mostly to provide a typesafe way of
having a collection of values which map to primitive values.

By your idea of the purpose of enums, yes, the OP's solution would
indeed defeat the purpose. I think you'll find you're in the minority
when it comes to that idea.
This may sound silly but.... For you to get the benefits of an Enum, you
have to USE the Enum, don't you think?... lol, no disrespect there. Consider
this:

Enum Juan
One
Two
End Enum

Dim SomeVariable as Juan
When you call it: SomeVariable = Juan.One

There you are limiting the value of SomeVariable to a limited range (the
Enum). Now, This is what the owner of this post proposes:

Enum Juan
One = 0
Two = 1
End Enum
Dim SomeVariable as Juan
When you call it: SomeVariable = One

First of all, how will the compiler be able to resolve this variable? It
will not be able to, because in this scope there is no such variable. There
is a reference however to Juan.One .
If the user wants to not qualify the name (which you can never do), wouldnt
it be the same as doing this?:

Dim SomeVariable as Juan
Dim One as integer = 0
When you call it: SomeVariable = One

The only difference would be that the enum would limit you to a defined
range. Other than that, this is the same, so IT DOES defeat the purpose of
having an Enum, which is why Enums exist, otherwise the language creators
wouldnt have bothered, don't you think?

Thank you.

--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Jon Skeet [C# MVP]" wrote:
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
Well, if you read the thread carefully you will see that I DID mention
Option Strict before.


Yes, but then you made blanket statements which didn't state that you
were essentially working in a non-typesafe way. You can't expect type
safety at all (at compile time) when you've got option strict turned
off. Do you actually write much code without option strict on?
But even with Option Strict ON you can still pass a
value from another Enum if you cast it.


Yes, if you cast it. In what way does that diminish the usefulness of
having compile-time type safety when you're *not* deliberately trying
to break things?
Nevertheless, because of all these comments, we are drifting away from the
point of this question, and I still stand on my ground: Refering to Enum
options without fully qualifying them defeats the purpose of having an Enum.


You seem to think that the sole purpose of enums is to force the
developer into fully qualifying names. I think that's a pretty narrow
idea of the purpose - for me, it's mostly to provide a typesafe way of
having a collection of values which map to primitive values.

By your idea of the purpose of enums, yes, the OP's solution would
indeed defeat the purpose. I think you'll find you're in the minority
when it comes to that idea.
You might as well declare variables or constants if you dont want to go
through the trouble of qualifying names.


Except then you lose the type safety, and could accidentally end up
using (say) an HTTP response code where you should actually be using a
file share mode.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 22 '05 #16

P: n/a
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
Once again, please read the posts above. I did talk about Option Strict.
You mentioned it in an earlier post, but not in the post which
specifically said that a call to TakeFirstEnum(SecondEnum.Fred)
succeeds. You didn't even mention it in the post before that. How was
anyone supposed to work out that you were talking about the (hopefully
unusual) situation of working with Option Strict off in a post made 16
hours after your only previous reference to Option Strict?
I clearly stated that you could CAST to the Enum type. Obviously IMPLICIT
conversions will yield an error with Option Strict ON, that is the whole
point of it.
Indeed.
As for the evaluation at runtime, because the compiler knows the type, a
constant or variable would provide THE SAME level of type safety.
No it wouldn't - because unless you declare a new type for each
constant (in which case you've basically got an enum anyway) you would
have to use the same type (eg Int32) for different types of constant,
at which point you *have* lost type safety.

In your first post in the thread, you said:

<quote>
That would defeat the purpose of having an Enum. you might as well
create three variables then.
</quote>

What type would you make those variables have?
The range of values IS part of the safety. If you don't believe me, read the
documentation and/or attempt to assign an integer outside of the range and
you will see what happens. E.g.:

Enum Juan
Zero 'By default this is initialized to 0
One 'By default this is initialized to 1
Two 'By default this is initialized to 2
End Enum

Public sub New()
Test(2) ------------> Option Strict OFF, this will be OK
Test(3) ------------> Option Strict OFF, this will FAIL
Test(ctype(2,Juan)) ------------> Option Strict ON, This will be OK
Test(ctype(3,Juan)) -------------> Option Strict ON, this will FAIL
End Sub
Unlike you, I've actually tried the code. Compile and run the
following:

Option Strict On

Imports System

Public Enum FirstEnum
Foo
Bar
Baz
End Enum

Public Class Test

Shared Sub TakeFirstEnum (value As FirstEnum)
Console.WriteLine (value)
End Sub

Shared Sub Main()
TakeFirstEnum(CType(5, FirstEnum))
End Sub
End Class

Compile it from the command line:
vbc Test.vb
Run it:
5

I think you'll agree that 5 is outside the range of the enum, and yet
it works. How do you explain that?
As you can see I am not *entirely* wrong. Try creating another Enum and pass
it to the function (with casting if using Option Strict ON) and you will see
that the value is accepted so long as it is in the range of the enum.
No, it's accepted whether or not it's in the range of the enum.
As far as ambiguity, a language can NEVER allow you to use the name
directly. Consider the following scenario:

Public Class One
Dim Juan as integer = 0
Enum Sample
Juan = 1
Javier = 2
End Enum
Public Sub New()
console.writeline(Juan) --------> * This will print "1"
End Sub
End Class

How will the compiler resolve this variable?
It can't. So in this case, the compiler would force you to
disambiguate. That doesn't mean there aren't many, many cases where
there *isn't* any ambiguity, and where the compiler could infer the
type.

<snip>
Finally, I never post anything until I try it myself.


Please explain how the code which you claim won't work works perfectly
fine then.

By the way, your test code also fails to compile because you haven't
declared the return type of your Test function, and because the enum
you declared was called "Juan" but you declared the parameter to the
function to be of type "JuanEnum". Here's your code tidied up. It
doesn't fail where you claimed it would, by the way.

Option Strict On

Imports System

Public Enum Juan
Zero 'By default this is initialized to 0
One 'By default this is initialized to 1
Two 'By default this is initialized to 2
End Enum
Public Class Foo

Public Shared Sub Test(ByVal e as Juan)
End Sub
Shared Sub Main()
Test(ctype(2,Juan))
Test(ctype(3,Juan))
End Sub
End Class
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 22 '05 #17

P: n/a
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
Yes, but then you made blanket statements which didn't state that you
were essentially working in a non-typesafe way. You can't expect type
safety at all (at compile time) when you've got option strict turned
off. Do you actually write much code without option strict on?
The issue at hand in this particular question is whether you could possibly
call a value from an Enum without qualifying the value, the discussion is not
about type safety.


It is when you say that getting rid of enforcing qualification removes
the whole point of enums - because that dismisses type safety as being
part of the useful purpose of using enums.
Anytime you assign a type of any kind to any variable you
get type safety, there is no argument there. It was the other reply that
introduced type safety into this thread. By the way, I ALWAYS code with
Option Strict ON.
Then why bother claiming that something succeeds (without saying under
what circumstances) when it would *never* succeed in the way you code?
Yes, if you cast it. In what way does that diminish the usefulness of
having compile-time type safety when you're *not* deliberately trying
to break things?


Again. Not talking about type safety here.


But I am, because it's a fundamental part of the purpose of enums.
By your idea of the purpose of enums, yes, the OP's solution would
indeed defeat the purpose. I think you'll find you're in the minority
when it comes to that idea.


This may sound silly but.... For you to get the benefits of an Enum, you
have to USE the Enum, don't you think?... lol, no disrespect there. Consider
this:

Enum Juan
One
Two
End Enum

Dim SomeVariable as Juan
When you call it: SomeVariable = Juan.One

There you are limiting the value of SomeVariable to a limited range (the
Enum). Now, This is what the owner of this post proposes:

Enum Juan
One = 0
Two = 1
End Enum
Dim SomeVariable as Juan
When you call it: SomeVariable = One

First of all, how will the compiler be able to resolve this variable?


By noting that the type is SomeVariable, that there is no other member
One which is available, and that One is a member of the Juan enum. It
could reasonably infer that Juan.One is what you're after.
It will not be able to, because in this scope there is no such variable.
Who says it has to resolve to a variable?
There is a reference however to Juan.One . If the user wants to not
qualify the name (which you can never do), wouldnt it be the same as
doing this?:

Dim SomeVariable as Juan
Dim One as integer = 0
When you call it: SomeVariable = One
No, it wouldn't - because the compiler would be able to notice that you
were referring to Juan.One implicitly, and that that was a reasonable
value for SomeVariable (because it's an element of Juan), whereas an
integer itself isn't an element of Juan. (Admittedly the constant 0 is
implicitly convertible to any enum, but that's a side issue.)
The only difference would be that the enum would limit you to a defined
range.
Again, it doesn't, as I've shown *several* times now. Please, please
compile one of the complete programs I've provided which shows it *not*
limiting anything to a defined range. It's just a case of copy, paste
into new text file, compile, and run.
Other than that, this is the same, so IT DOES defeat the purpose of
having an Enum, which is why Enums exist, otherwise the language creators
wouldnt have bothered, don't you think?


No, it doesn't defeat the purpose because type safety isn't lost.

You *could* declare three variables:
Dim One as Juan = Juan.One
etc

but doing that everywhere you use the enum would get old very quickly -
and it's unnecessary.
For what it's worth, Java now has the ability to do "static imports"
which allow for precisely this kind of thing - and guess what? The
world keeps moving, and you don't lose any of the benefits of enums
etc. (Admittedly Java enums are somewhat different to .NET enums -
vastly superior IMO - but the principle is the same.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 22 '05 #18

P: n/a
Small correction to my last post. The console line would print 0.

My apologies for any confussion. It's been a long day... >: )

--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Madestro" wrote:
Once again, please read the posts above. I did talk about Option Strict.

I clearly stated that you could CAST to the Enum type. Obviously IMPLICIT
conversions will yield an error with Option Strict ON, that is the whole
point of it.

As for the evaluation at runtime, because the compiler knows the type, a
constant or variable would provide THE SAME level of type safety.

The range of values IS part of the safety. If you don't believe me, read the
documentation and/or attempt to assign an integer outside of the range and
you will see what happens. E.g.:

Enum Juan
Zero 'By default this is initialized to 0
One 'By default this is initialized to 1
Two 'By default this is initialized to 2
End Enum

Public sub New()
Test(2) ------------> Option Strict OFF, this will be OK
Test(3) ------------> Option Strict OFF, this will FAIL
Test(ctype(2,Juan)) ------------> Option Strict ON, This will be OK
Test(ctype(3,Juan)) -------------> Option Strict ON, this will FAIL
End Sub

Public Function Test(ByVal e as JuanEnum)

End Function

As you can see I am not *entirely* wrong. Try creating another Enum and pass
it to the function (with casting if using Option Strict ON) and you will see
that the value is accepted so long as it is in the range of the enum.

As far as ambiguity, a language can NEVER allow you to use the name
directly. Consider the following scenario:

Public Class One
Dim Juan as integer = 0
Enum Sample
Juan = 1
Javier = 2
End Enum
Public Sub New()
console.writeline(Juan) --------> * This will print "1"
End Sub
End Class

How will the compiler resolve this variable?
Answer: 1 . It needs the fully qualified name of the variable in order to
know you want the Enum and not the local variable. How can you possible have
two variables with the same name in the same scope?

Finally, I never post anything until I try it myself.

Thank you!
--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Jon Skeet [C# MVP]" wrote:
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
I am not sure what language you are coding in


C#.
but at least in VB.NET you are incorrect.


Not with option strict on. If you're programming with option strict
off, that's a different matter - you've given up any vestige of compile
time type safety already.
Here are the TRUE results:

TakeFirstEnum(Foo) --> FAILS
TakeFirstEnum(FirstEnum.Foo) --> SUCCEEDS
TakeSecondEnum(Fred) --> FAILS
TakeSecondEnum(SecondEnum.Fred) --> SUCCEEDS

TakeFirstEnum(Fred) --> FAILS
TakeFirstEnum(SecondEnum.Fred) --> SUCCEEDS
TakeSecondEnum(Foo) --> FAILS
TakeSecondEnum(FirstEnum.Foo) --> SUCCEEDS


The failures are all because the language doesn't allow what's being
proposed, of course.

However, I don't get the same results as you. Here's a short but
complete program to demonstrate:

Option Strict On

Imports System

Public Enum FirstEnum
Foo
Bar
Baz
End Enum

Public Enum SecondEnum
Fred
George
Harry
End Enum
Public Class Test

Shared Sub TakeFirstEnum (value As FirstEnum)
Console.WriteLine (value)
End Sub

Shared Sub TakeSecondEnum (value As SecondEnum)
Console.WriteLine (value)
End Sub

Shared Sub Main()
TakeFirstEnum(FirstEnum.Foo)
TakeFirstEnum(SecondEnum.Fred)
TakeSecondEnum(FirstEnum.Foo)
TakeSecondEnum(SecondEnum.Fred)
End Sub
End Class

Compiling the above gives:
c:\test\Test.vb(30) : error BC30512: Option Strict On disallows
implicit conversions from 'SecondEnum' to 'FirstEnum'.

TakeFirstEnum(SecondEnum.Fred)
~~~~~~~~~~~~~~~
c:\test\Test.vb(31) : error BC30512: Option Strict On disallows
implicit conversions from 'FirstEnum' to 'SecondEnum'.

TakeSecondEnum(FirstEnum.Foo)
~~~~~~~~~~~~~

Turning option strict off, it compiles fine, but as I said, if you're
running with option strict off I have very little sympathy with any
type safety issues you may run into :)
Like I said before, ultimately, the enum evaluates to a constant


Of the appropriate type though - the type of the expression is known to
the compiler.
so there
is really no "type safety" here, except for the type of the constant and the
range of valid values the enum provides.


Actually, the range of valid values the enum provides *isn't* part of
the safety - you can cast any value from the underlying type.
Because of this, I could call the first function with a value from
the second Enum so long as it evaluates to a value within the range
of the first Enum.


That's *entirely* wrong. With option strict on you can't call it at
all, and with option strict you can call it whether it's in the range
or not.
What I cannot do however is call one of the values of the Enum
without fully qualifying it because once again, like I said before)
you would run into ambiguity problems.


Well, you can't do it at the moment because the language specification
says you can't. There's nothing to stop the language specification from
changing to allow you to do it where there was no ambiguity - and that
change *wouldn't* lose the whole point of enums.
It may not be the case in the language you are using, but it certainly is
the case with VB.NET. Try it, you will see.


I tried it, and found what you asserted to be wrong - did you actually
try it, or were you making assumptions?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 22 '05 #19

P: n/a
> You mentioned it in an earlier post, but not in the post which
specifically said that a call to TakeFirstEnum(SecondEnum.Fred)
succeeds. You didn't even mention it in the post before that. How was
anyone supposed to work out that you were talking about the (hopefully
unusual) situation of working with Option Strict off in a post made 16
hours after your only previous reference to Option Strict?
Understandable. I should not expect you to remember and be more clear on my
answers.
No it wouldn't - because unless you declare a new type for each
constant (in which case you've basically got an enum anyway) you would
have to use the same type (eg Int32) for different types of constant,
at which point you *have* lost type safety.
Actually you would have to declare the SAME type for each constant, and
indeed you would have an Enum, and you WOULD have to use the same type on the
function that receives them so you really DON'T loose type safety.
I think you'll agree that 5 is outside the range of the enum, and yet
it works. How do you explain that?
You could not be more right. I actually missread the documentation. The
limit is in the value size. For example, if you have an Enum defined as
integer, then you could still use other values so long as they are within the
range of an integer.
Totally my fault, I take it back.
It can't. So in this case, the compiler would force you to
disambiguate. That doesn't mean there aren't many, many cases where
there *isn't* any ambiguity, and where the compiler could infer the
type.
The compiler may infer the type, but not the value. The value has to be
resolved by a fully qualified name. The compiler cannot possibly resolve that.
Please explain how the code which you claim won't work works perfectly
fine then.
I am not sure what code you refer to.
By the way, your test code also fails to compile because you haven't
declared the return type of your Test function, and because the enum
you declared was called "Juan" but you declared the parameter to the
function to be of type "JuanEnum". Here's your code tidied up. It
doesn't fail where you claimed it would, by the way.
I turned Option Strict OFF to test this, which is why the function had no
return type.
JuanEnum is just a typo when copying back to here. I don't copy and paste.
Yes, the code will not fail. This relates to my first answer in this posting.

Thank you!

--
Juan Romero
-----------------------------------------
The successful person has the habit of doing the things failures don't like
to do.
E.M. Gray
"Jon Skeet [C# MVP]" wrote:
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
Once again, please read the posts above. I did talk about Option Strict.


You mentioned it in an earlier post, but not in the post which
specifically said that a call to TakeFirstEnum(SecondEnum.Fred)
succeeds. You didn't even mention it in the post before that. How was
anyone supposed to work out that you were talking about the (hopefully
unusual) situation of working with Option Strict off in a post made 16
hours after your only previous reference to Option Strict?
I clearly stated that you could CAST to the Enum type. Obviously IMPLICIT
conversions will yield an error with Option Strict ON, that is the whole
point of it.


Indeed.
As for the evaluation at runtime, because the compiler knows the type, a
constant or variable would provide THE SAME level of type safety.


No it wouldn't - because unless you declare a new type for each
constant (in which case you've basically got an enum anyway) you would
have to use the same type (eg Int32) for different types of constant,
at which point you *have* lost type safety.

In your first post in the thread, you said:

<quote>
That would defeat the purpose of having an Enum. you might as well
create three variables then.
</quote>

What type would you make those variables have?
The range of values IS part of the safety. If you don't believe me, read the
documentation and/or attempt to assign an integer outside of the range and
you will see what happens. E.g.:

Enum Juan
Zero 'By default this is initialized to 0
One 'By default this is initialized to 1
Two 'By default this is initialized to 2
End Enum

Public sub New()
Test(2) ------------> Option Strict OFF, this will be OK
Test(3) ------------> Option Strict OFF, this will FAIL
Test(ctype(2,Juan)) ------------> Option Strict ON, This will be OK
Test(ctype(3,Juan)) -------------> Option Strict ON, this will FAIL
End Sub


Unlike you, I've actually tried the code. Compile and run the
following:

Option Strict On

Imports System

Public Enum FirstEnum
Foo
Bar
Baz
End Enum

Public Class Test

Shared Sub TakeFirstEnum (value As FirstEnum)
Console.WriteLine (value)
End Sub

Shared Sub Main()
TakeFirstEnum(CType(5, FirstEnum))
End Sub
End Class

Compile it from the command line:
vbc Test.vb
Run it:
5

I think you'll agree that 5 is outside the range of the enum, and yet
it works. How do you explain that?
As you can see I am not *entirely* wrong. Try creating another Enum and pass
it to the function (with casting if using Option Strict ON) and you will see
that the value is accepted so long as it is in the range of the enum.


No, it's accepted whether or not it's in the range of the enum.
As far as ambiguity, a language can NEVER allow you to use the name
directly. Consider the following scenario:

Public Class One
Dim Juan as integer = 0
Enum Sample
Juan = 1
Javier = 2
End Enum
Public Sub New()
console.writeline(Juan) --------> * This will print "1"
End Sub
End Class

How will the compiler resolve this variable?


It can't. So in this case, the compiler would force you to
disambiguate. That doesn't mean there aren't many, many cases where
there *isn't* any ambiguity, and where the compiler could infer the
type.

<snip>
Finally, I never post anything until I try it myself.


Please explain how the code which you claim won't work works perfectly
fine then.

By the way, your test code also fails to compile because you haven't
declared the return type of your Test function, and because the enum
you declared was called "Juan" but you declared the parameter to the
function to be of type "JuanEnum". Here's your code tidied up. It
doesn't fail where you claimed it would, by the way.

Option Strict On

Imports System

Public Enum Juan
Zero 'By default this is initialized to 0
One 'By default this is initialized to 1
Two 'By default this is initialized to 2
End Enum
Public Class Foo

Public Shared Sub Test(ByVal e as Juan)
End Sub
Shared Sub Main()
Test(ctype(2,Juan))
Test(ctype(3,Juan))
End Sub
End Class
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 22 '05 #20

P: n/a
Madestro <me_no_like_spam_juanDOTromero@bowneDOTcom> wrote:
You mentioned it in an earlier post, but not in the post which
specifically said that a call to TakeFirstEnum(SecondEnum.Fred)
succeeds. You didn't even mention it in the post before that. How was
anyone supposed to work out that you were talking about the (hopefully
unusual) situation of working with Option Strict off in a post made 16
hours after your only previous reference to Option Strict?
Understandable. I should not expect you to remember and be more clear on my
answers.


It's not a case of not remembering, so much as you did nothing to
indicate that you intended any other posts to assume that Option Strict
would be off in any code you referred to.
No it wouldn't - because unless you declare a new type for each
constant (in which case you've basically got an enum anyway) you would
have to use the same type (eg Int32) for different types of constant,
at which point you *have* lost type safety.


Actually you would have to declare the SAME type for each constant, and
indeed you would have an Enum, and you WOULD have to use the same type on the
function that receives them so you really DON'T loose type safety.


In that case, you just didn't explain yourself clearly in the first
place. I thought you meant getting rid of the enum entirely and *just*
having three variables, eg of type Int32.

If you're just suggesting creating three variables of the same type as
the enum but within the class which wishes to use them, that would
indeed still be type safe - but much less convenient than the compiler
inferring it for you.
I think you'll agree that 5 is outside the range of the enum, and yet
it works. How do you explain that?


You could not be more right. I actually missread the documentation. The
limit is in the value size. For example, if you have an Enum defined as
integer, then you could still use other values so long as they are within the
range of an integer.
Totally my fault, I take it back.


Goodo.
It can't. So in this case, the compiler would force you to
disambiguate. That doesn't mean there aren't many, many cases where
there *isn't* any ambiguity, and where the compiler could infer the
type.


The compiler may infer the type, but not the value. The value has to be
resolved by a fully qualified name. The compiler cannot possibly resolve that.


Yes it can - by seeing what type is expected! What is to stop the
compiler from seeing that the expected type for a parameter, or
assignment, or whatever, is the enum, and looking up the expression as
a member of the enum?

It certainly wouldn't be unambiguous all the time, but it doesn't need
to be.

In C# it would present some interesting "purity" discussions in the
same way that people sometimes propose overloading by return type - I
don't know if the same would be true in VB.NET. However, whether it's
"pure" or not doesn't affect whether it's *possible*.
Please explain how the code which you claim won't work works perfectly
fine then.


I am not sure what code you refer to.


The code you took back, which you said would fail due to the range of
the enum.
By the way, your test code also fails to compile because you haven't
declared the return type of your Test function, and because the enum
you declared was called "Juan" but you declared the parameter to the
function to be of type "JuanEnum". Here's your code tidied up. It
doesn't fail where you claimed it would, by the way.


I turned Option Strict OFF to test this, which is why the function had no
return type.
JuanEnum is just a typo when copying back to here. I don't copy and paste.


Why don't you copy and paste? It makes life much easier for people who
want to try your code, because it means they can try the *actual* code
that you wrote.
Yes, the code will not fail. This relates to my first answer in this posting.


Indeed.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 22 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.