Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 207
  • Last Modified:

Where to put enumerations?

I have an SMTP class which sets the following property

 Public Property SmtpSAuthenticationType() As AuthenticationTypeException.AuthenticationType
        Get
            Return _smtpSAuthenticationType
        End Get
        Set(ByVal value As AuthenticationTypeException.AuthenticationType)
            Try
                If Not [Enum].IsDefined(GetType(AuthenticationTypeException.AuthenticationType), value) Then
                    Throw New AuthenticationTypeException
                End If
                _smtpSAuthenticationType = value
            Catch ex As Exception
                _errors.Add("SMTP Server Authentication Type", ex.Message)
            End Try
        End Set
    End Property

I have defined the enumeration in the exception, should it be in the class instead?
0
rocky050371
Asked:
rocky050371
  • 7
  • 6
1 Solution
 
rocky050371Author Commented:
As an addition to that if I am using a flags enumeration should they be decalred in the same place too
0
 
käµfm³d 👽Commented:
This:

If Not [Enum].IsDefined(GetType(AuthenticationTypeException.AuthenticationType), value) Then

Open in new window


doesn't really benefit you. You have defined the type of SmtpSAuthenticationType to be AuthenticationTypeException.AuthenticationType, so anybody using your code is restricted to assigning values of that type--otherwise a compiler error is generated. The only reason I could think to have code like this is if your property were being assigned via reflection, but I believe even then, an error would occur (a runtime error) due to trying to assign an inappropriate value.

I have defined the enumeration in the exception, should it be in the class instead?
I believe MS suggests enums get their own code file, although they seem to have done a good job of creating enums and other classes inside of other classes, themselves! Put your enum wherever it is the most logical. To me, including the enum inside of the AuthenticationTypeException class seems a bit counter-intuitive.
0
 
rocky050371Author Commented:
there is a try block around it, surely checking whether the value is defined within the enumeration provides feedback to those who are consuming the business object
0
Veeam Task Manager for Hyper-V

Task Manager for Hyper-V provides critical information that allows you to monitor Hyper-V performance by displaying real-time views of CPU and memory at the individual VM-level, so you can quickly identify which VMs are using host resources.

 
rocky050371Author Commented:
or in fact should I set the property to an integer then check it within the assignment?
0
 
käµfm³d 👽Commented:
You're missing what I'm saying. The type of value inside your set will ALWAYS be AuthenticationTypeException.AuthenticationType. The compiler won't allow you to pass in "cat", 1, new Boat(), etc. You always have to assign a value of type AuthenticationTypeException.AuthenticationType to the SmtpSAuthenticationType member. In other words:

Good
obj.SmtpSAuthenticationType = AuthenticationTypeException.AuthenticationType.FirstEnumMember
obj.SmtpSAuthenticationType = DirectCast(1, AuthenticationTypeException.AuthenticationType)

Open in new window


Bad
obj.SmtpSAuthenticationType = "cat"
obj.SmtpSAuthenticationType = 1
obj.SmtpSAuthenticationType = new Boat()

Open in new window



Note, the difference between #2 Bad and #2 Good is that the good version has an explicit cast. This is assuming you don't have Option Strict set to Off.
0
 
rocky050371Author Commented:
I appreciate what you are saying, but to cater for any value being passed in is it better then for calling object to treat the public property as an integer then cast it to the enum for internal use?
0
 
käµfm³d 👽Commented:
but to cater for any value being passed in is it better then for calling object to treat the public property as an integer then cast it to the enum for internal use?
If you were to change the type of SmtpSAuthenticationType to int, then you would want the if logic, because int can hold many more values than what you would probably define in your AuthenticationType enum. The benefit of using an enum over an int is that your range of valid values is restricted to only those defined by the enum; if you use an int, then your possible values become -2147483648 to 2147483647, but you enum may only define 1 to 5. This is why you would want a check like what you have--to weed out the other 4294967291 values that don't correspond to a valid enum value. If you keep the enum as the type of your SmtpSAuthenticationType property, then you avoid having to check for these unacceptable values.
0
 
rocky050371Author Commented:
but this then  relies on the calling program to know that the public property only accepts a value within the allowed range.

How would you deal with this?

Presumably if I am right in thinking that removing he enum check is also effectively removing the business rule




0
 
käµfm³d 👽Commented:
It looks like I might be eating crow after this conversation  : \

In testing my assertions, it seems that VB is a tad more "forgiving" than C# is, even though we're still playing in .NET land. Passing in a casted value to an a field/property of type enum will still allow you to store the value without error--C# would not allow this. For example:

Module Module1

    Sub Main()
        Dim x As AuthenticationType = 1700

        Console.WriteLine(x.ToString())
        Console.ReadKey()
    End Sub

End Module

Public Enum AuthenticationType
    FirstEnumMember = 1
End Enum

Open in new window


I've only defined one enum member: FirstEnumMember. Its value is 1. However, in my test code, I am casting the value of 1700 to the enum's type. The assignment will succeed, but when the ToString call hits, you will simply see the value 1700 rather than the default of the enum member's name--if you assigned the value of FirstEnumMember to the variable x, the ToString call would print "FirstEnumMember" and not "1".

Based on this test, you are correct in your logic for the property. If you ever switch to C#, you shouldn't need such logic  = )
0
 
rocky050371Author Commented:
:-)

I would still be interested to know how you would do it, would you always just force consumers to pass a correct range value in, or would you switch it to an int etc


0
 
käµfm³d 👽Commented:
I would use an enumeration because it associates friendly names with values. It much easier to remember:

Public Enum LampState
    Off = 0
    On = 1
End Enum

than it is to remember:

obj.LampState = 1  ' Lamp is on

Open in new window


especially since Intellisense will pop up and list "Off" and "On" as possible values when using an enumeration.

In reality, enumerations are integer values under the hood anyway, so when using an enum, you are still using an int--you just get a friendly name associated with the value.
0
 
käµfm³d 👽Commented:
Correction to my first example (to make it more in line with the second:

Public Enum LampState
    Off = 0
    On = 1
End Enum

Open in new window


obj.LampState = LampState.Off

Open in new window

0
 
käµfm³d 👽Commented:
Another benefit to using enumerations is that if the value of any particular enum member ever needs to change, then you can simply change it in the definition of the enum rather than searching for every spot where you used a "1" in code. So my last example could be:

Public Enum LampState
    Off = 2  ' The boss decided that 2 makes more sense as an "off" value
    On = 1
End Enum

Open in new window


Now our other code doesn't need to be changed:

obj.LampState = LampState.Off

Open in new window


because we simply changed the definition.
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now