0

I'm aware that many questions are similar, but possibly because many relate to C# that I can't easily translate to VB.Net, I can't find a way for the following anywhere. A function Test gets a parameter TypToValidate that specifies a Type to check against.

The code in the function reads a chunk of a line from a text into a String variable. Based on what is read, that string may be "abc" or "0.307" or "12" or whatever else. The function then has to check if that string can be cast into the Type specified by TypeToValidate. If so, the function returns the validated chunk of text as a string; if not, it throws an error.

Function Test(... , Optional ByVal TypeToValidate as Type = String) as String
  ChunkOfText = SomeFile.ReadLine
  If TypeOf(ChunkOfText) Is TypeToValidate Then 
    Return ChunkOfText
  Else
    Throw ex As ApplicationException ' or whatever like this
  End If 
  ...

I understand that 'Type' cannot itself be used as a TYPE, the TYPE of Types, conaining Types as values. I.o.w., I cannot pass a type to a function, or can I?

Obviously, I could use

Function Test(..., Optional ByVal TypeToValidate as String = "String") as String

and pass a String (like 'Byte', 'Integer', 'Int32', ...) to the function instead of a Type, but that does't seem very professional... and allows for errors. Any help, preferably in VB.Net?

CeSinge
  • 21
  • 6
  • GetType(String), but that cannot be used as the default of an Optional parameter. VB has no syntax to generate a *constant expression* of type Type. It is in good company, C# [does not either](https://stackoverflow.com/questions/32212815/why-cant-a-type-be-used-as-a-constant-value). You can't get a good alternative when you don't describe why you need it. – Hans Passant Nov 21 '20 at 16:09
  • I've expanded my question to better convey what I'm trying to achieve. In my first attempt, I tried to be brief, but obviously failed. Sorry. – CeSinge Nov 21 '20 at 20:04
  • 1
    Note that `TypeOf(ChunkOfText)` is always `String`. The text this string contains does not matter. – Olivier Jacot-Descombes Nov 21 '20 at 21:13

2 Answers2

0

I don't think that an optional parameter works here, since it must be initialized with a constant expression.

A variable of type Type must be compared to another expression of type Type with =. This simply tests whether the two values are equal.

Function Test(someVar As Object, typeToValidate As Type) As Boolean
    Return someVar?.GetType() = typeToValidate
End Function

.GetType() applied to a variable gets a Type object describing the runtime type of the object.

(I used a null-conditional operator here in case the value is Nothing.)


Another possibility is to use a generic function and to test with TypeOf someVar Is T where T is a type name (given as an identifier, not as a String) or a generic type parameter.

Function Test(Of T)(someVar As Object) As Boolean
    Return TypeOf someVar Is T
End Function

Then, we can test with

Dim obj As Object
obj = "Hello"

If Test(Of String)(obj) Then
    Console.WriteLine("obj is a String")
End If

See: Generic Procedures in Visual Basic


Note also that there is not point in writing something like

If someCondition Then
    Return True
Else
    Return False
End If

someCondition (which can be a any Boolean expression) already yields the values True or False. Therefore, you can simply return it with

Return someCondition
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • Can't you use 'Nothing' as the optional default? – Dave Doknjas Nov 21 '20 at 16:14
  • Yes, that's an idea. Then, when `typeToValidate` is `Nothing` we would test if the `someVar` is a `String`; however, it is not obvious for a caller to know what kind of test will be performed. I think it is better to pass the type explicitly. – Olivier Jacot-Descombes Nov 21 '20 at 16:23
  • These two versions of `Test` can be used as overloaded methods (what I actually did when testing my code examples). – Olivier Jacot-Descombes Nov 21 '20 at 16:29
  • Because the function is already called from many places, the new `TypeToValidate` parameter _must_ be `Optional`. `Nothing` works indeed, but then, oddly, `TypeToValidate' remains `Nothing` even if I try to assign a value to it like `TypeToValidate = GetType(String)` – CeSinge Nov 21 '20 at 20:08
  • @OlivierJacot-Descombes Thank you for your very simple and clear example of a generic function! I'll keep that. – CeSinge Nov 21 '20 at 20:11
0

Or you can use:

Even that seems a strange request (everyone have its reasons) it is possible in some ways which are all valid. As above by Olivier or how the code below shows. You ca use also the Type parameter as Optional but the dilemma is when that optional still remain Nothing. In this case doesn’t represent the tested type.

Function Test(SomeVars As Object, Optional ByVal TypeToValidate As Type = Nothing) As Boolean
    Return TypeToValidate IsNot Nothing AndAlso TypeToValidate.Equals(SomeVars.GetType)
End Function

Usage:

    Console.WriteLine("Test String 'Is String'" & Test("Is String", GetType(String)).ToString)
    Console.WriteLine("Test Integer for 10 " & Test(10, GetType(Integer)).ToString)
    Console.WriteLine("Test Integer for 12.12 " & Test(12.12, GetType(Integer)).ToString)
G3nt_M3caj
  • 2,497
  • 1
  • 14
  • 16
  • You could also simply write `Return TypeToValidate IsNot Nothing AndAlso TypeToValidate.Equals(SomeVars.GetType)`. An `If` statement and a second `Return` statement are not required. – Olivier Jacot-Descombes Nov 21 '20 at 16:32
  • Looks promising, but as indicated, `TypeToValidate` then always seems to remain `Nothing`. I'm then also unable to do a `CType`, `TryCast` in the function against `TypToValidate`. – CeSinge Nov 21 '20 at 20:14