Get the Integer value of an enumeration which is a generic - vb.net

Here is the basic situation.
Public Class MyEnumClass(of T)
Public MyValue as T
End Class
This is vast oversimplification of the actual class, but basically I know that T is an enumeration (if it is not then there will be many other problems, and is a logical error made by the programmer)
Basically I want to get the underlying integer value of MyValue.
Using Cint or Ctype, does not work.

I was going to use a cool piece of reflection code but just a simple Convert.ToInt32 works great... Forgive my VB I'm a C# guy
Public Function GetEnumInt(Of T)(enumVal As T) As Integer
Return Convert.ToInt32(enumVal)
End Function

I tried this and it worked:
String.Format("{0:d}", MyValue)

I know you can do the following to get all the underlying values (I hope my VB syntax is correct... I've been working in C# mostly of late):
Dim intVal As Integer
For Each intVal In [Enum].GetValues(GetType(T))
//intValue is now the enum integer value
Next
That might at least get you started in the right direction.

This also works :
Fix(enumval)

Another simple way in VB.NET is to add it to 0:
Dim intVal As Integer = 0 + myEnum
So, this should work:
Sub GetEnumInt(of T)(enumVal as T) as Int
return 0 + enumVal
End Sub

Thanks to 'Jon Skeet'. But his code does not work in my Excel-2016. Minwhile the next code works fine:
Public Enum TypOfProtectWs
pws_NotFound = 0
pws_AllowAll = 1
pws_AllowFormat = 2
pws_AllowNone = 3
End Enum
Private Function TypOfProtectWs2I(pws As TypOfProtectWs) As Integer
TypOfProtectWs2I = Format("0", pws)
End Function
Private Sub test_TypOfProtectWs2I()
Debug.Print TypOfProtectWs2I(pws_AllowAll)
End Sub

Related

Returning a object with functions in vb.net

I'm using a COM interface to get some kind of technical sub structures from 3rd part program but before that i'm listing how many substructures in the model after that i'd like to assign that to my Substr parameter.
Private Shared Function checkListSubSubstrs(ByVal Substrs As IScrNamedObjectList)
Dim Substr As IScrSubstructure
Dim nSubstr As Integer
nSubstr = Substrs.count
For i As Integer = 0 To nSubstr - 1
Substr = Substrs.item(i)
Next
Return Substr
End Function
How can i get the Substr object because if i'm using like that (above code structure) visual studio warns me like below;
"Variable 'Substr' is used before it has benn assigned a value. A null
reference exception could result at runtime"
Based on what I understand your question to be, you would do something like this:
Private Shared Function GetSomePropertyValues(substructures As IScrNamedObjectList) As SomeType()
Dim values As New List(Of SomeType)
For i = 0 To substructures.Count - 1
value.Add(substructures.Item(i).SomeProperty)
Next
Return values.ToArray()
End Function
You might also be able to use LINQ, although I'm not 100% sure with COM interfaces. You could try something like this:
Private Shared Function GetSomePropertyValues(substructures As IScrNamedObjectList) As SomeType()
Return substructures.Cast(Of IScrSubstructure)().
Select(Function(s) s.SomeProperty).
ToArray()
End Function

VBA call class property from the class

In a VBA class module (let's say in Excel or Access), I wrote a function SomeFunction() returning a value.
If I call this from another function/sub in the class, should I call it:
a) this way: myVar = SomeFunction or
b) this way: myVar = Me.SomeFunction ?
I think both work, so except for the writing style and clarifying SomeFunction is part of the class, does it make any difference?
Both are indeed valid, but way B should be preferred since it's more explicit what you're doing.
Consider the following (valid) class code:
Public Property Get SomeValue() As Integer
SomeValue = 5
End Property
Public Property Get AnotherValue() As Integer
Dim SomeValue As Integer
SomeValue = 3
AnotherValue = SomeValue 'Returns 3
Debug.Print Me.SomeValue 'Returns 5
End Property
Because you can (but shouldn't) do this in VBA, it's a good practice to use Me. to make it clear you're using a class property and not a variable.
As far as I know - It does not make any difference.
However, if you use Me. in the class, you can use the Intellisense to see the available subs, functions and properties, which could be a bit handy:
However, I prefer not to use the Me.
If you are having the following in a module:
Public Function Foo()
Foo = 5
End Function
Sub TestMe()
Dim cls As New Klasse1
cls.TestMe
End Sub
And then the following in Klasse1:
Sub TestMe()
Debug.Print Modul1.Foo
Debug.Print Me.Foo
Debug.Print Foo
End Sub
Function Foo()
Foo = 10
End Function
it is visible that the existense of Me. is just syntax sugar.

VB Nullables and Nothings

I researched C#'s default keyword equivalence in VB.NET and came across this question.
Then I got curious. Some background - I'm working with parsing an excel spreadsheet, where many columns can be null, and there is certainly a difference for me between an integer column being 0 and being null.
I wrote a little parse method:
Function Test(ByVal i As String) As Nullable(Of Integer)
Dim j As Integer
If Integer.TryParse(i, j) Then
Return j
Else
Return Nothing
End If
End Function
this seems to work correctly. But here, I can return an Integer if i want:
Function Test(ByVal i As String) As Nullable(Of Integer)
Return 2 'or Return Nothing
End Function
which I can in C# as well:
static void Main(string[] args)
{
int? j = Test("1");
}
public static int? Test(string i)
{
return 2; //or return null
}
In the code above, if I change j to an int, I'll get a compile-time conversion error, which makes total sense.
Now my question - in VB, if i attempt a similar approach:
Sub Main()
Dim j As Integer = Test("hello")
End Sub
Function Test(ByVal i As String) As Nullable(Of Integer)
Dim j As Integer
Return If(Integer.TryParse(i, j), j, Nothing)
End Function
or, in my test case where i is not an Integer it can be rewritten as:
Function Test(ByVal i As String) As Nullable(Of Integer)
Return DirectCast(Nothing, Integer)
End Function
because of the way Nothing works in VB.NET, this code compiles and runs without error -- j is set to Integer's default 0.
This feels so dirty to me. In this scenario you can somewhat alter the method's intentions without any warnings or errors. I'm just curious I suppose, is this an unintentional by-product of the way Nothing works in VB, or is this the intended purpose?
Your VB.Net code compiles because you're using late binding, which allows changing the type of a variable at runtime.
If you compile your code with OPTION STRICT ON, you'll get a compiler error like:
Option Strict On disallows implicit conversions from 'Integer?' to 'Integer'.
You can't assign NULL to a value type in VB.Net in which it instantiates that type with its default value. In your case you are not creating a NULL Integer, but an integer that holds the default value of 0.
Another good note: turn Option Strict On

Performance Enum vs class?

i found few new style (for me) to "define" output from select query.
Private Enum Item
ID
Item
Description
End Enum
Private Class Item
Private ID as String
Private Item as String
Private Desc as String
End Class
I 'm thinking of using either one of them. by using class i does not need to re-cast the element type before i display. but Enum seems like easier to understand.
Anyone have some suggestion how to decide?
Enum members are numeric (usually integer, but can be long). But they are not variable and do not change at runtime. So your enum equates to:
Private Enum Item
ID = 0
Item = 1
Description = 2
End Enum
If you want Description to be a string, then a class is a better idea. Enums are used to reference or index something or limit/define a selection. Like:
Public Property Stooge As Stooges
Friend Enum Stooges
Larry
Moe
Curly
Shemp
CurlyJoe
End Enum
The Stooge Property must be one of those values. in code it will show you the text ("moe") but store and integer (1). users will be shown the text in drop downs etc.
You can associate a description with Enum constants:
Public Enum Stooges
<Description("Larry - Funny one")> Larry
<Description("Moe - 'Smart' One")> Moe
<Description("Curly - Sore One")> Curly
<Description("Shemp - One with bad haircut")> Shemp
<Description("CurlyJoe - Last one")> CurlyJoe
End Enum
To get the description for a single one:
Public Shared Function GetDescription(ByVal EnumConstant As [Enum]) As String
Dim fi As Reflection.FieldInfo =
EnumConstant.GetType().GetField(EnumConstant.ToString())
Dim attr() As DescriptionAttribute =
DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute),
False), DescriptionAttribute())
If attr.Length > 0 Then
Return attr(0).Description
Else
Return EnumConstant.ToString() ' return enum name if no Descr
End If
End Function
Usage: str = enumHelper.GetDescription(Stooge.Moe) (enumHelper is the name of the calss where the static/shared function resides).
To get a String Array of all the descriptions:
Public Shared Function GetDescriptions(ByVal type As Type) As String()
Dim n As Integer = 0
Dim enumValues As Array
Try
enumValues = [Enum].GetValues(type)
Dim Descr(enumValues.Length - 1) As String
For Each value As [Enum] In enumValues
Descr(n) = GetDescription(value)
n += 1
Next
Return Descr
Catch ex As Exception
MessageBox.Show(ex.Message)
Return Nothing
End Try
End Function
Usage: Dim strEnum As String() = enumHelper.GetDescriptions(GetType(Stooges))
From your question, what you really mean is Struct vs Class. I would default to creating a class. The main reason to use a struct vs a class, is when you need value semantics -- assignment/parameters copies the bits, not a pointer. This is fairly rare in my experience. Unless you have a compelling reason (and you know the difference), go with a class.

LINQ VB.net Return Single Type of Object Invalid Cast

Ok, just needing a 2nd set of eyes looking at this to make sure the error isn't something else other than my LINQ code here. Here's the function class itself:
Public Function GetJacketByPolicyID(ByVal jacketID As Int32) As tblPolicy
Dim db As New DEVDataContext()
Dim j As tblPolicy = db.tblPolicies.Single(Function(p) p.policyNumber = jacketID)
Return j
End Function
and here is the code which calls this class function in the web control form itself:
Dim p As tblPolicy
Dim j As New Jackets()
p = j.GetJacketByPolicyID(3000050)
For some reason it's flagging the 2nd line in the GetJacketByPolicyID function saying the specified cast is not valid. So I'm guessing it's something I'm doing wrong. I'm sure the tblPolicy/tblPolicies class works right since I can create a new instance of a tblPolicy and set a few variables by hand and return it, so that's not it. I've also checked the datarow I'm fetching and there's no null values in the record, so that shouldn't be it either.Any help much appreciated.
This would seem to get what you are looking for. Not sure why you are passing in a function for a simple query like this.
Public Function GetJacketByPolicyID(ByVal jacketID As Int32) As tblPolicy
Dim _jacket as tblPolicy
Using _db As New DEVDataContext()
_jacket = (From _j In db.tblPolicies Where _j.policyNumber.Equals(jacketID) Select _j).Single()
End Using
Return _jacket
End Function