Results 1 to 27 of 27

Thread: Generic type conversion function CType

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Generic type conversion function CType

    I want to write a generic function to convert between arbitrary types, for example:
    Code:
    TheValue = CType(obj, MyClass)
    
    TheValue2 = CType(obj, MyClass2)
    The parameters of the function are as follows:
    Code:
    Public Function CType(ByVal Value As Variant, DestType As TypeOrClassName) As Variant
    
    End Function
    I'd like to hear everyone's advice. Thanks.

  2. #2
    The Idiot
    Join Date
    Dec 2014
    Posts
    3,002

    Re: Generic type conversion function CType

    what u mean?
    just
    Set Obj = Nothing
    Set Obj = New MyClass

    Obj need to be Variant.

  3. #3
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    The CType operator in VB.Net is actually dependent on the operator itself being overloaded on the type being converted. Unfortunately, VB6 doesn't have operator overloading.

    If this is for your transpiler. You could translate conversions between primitive types like Integers, Strings etc using normal VB6 conversion functions like CInt and CStr. For classes, you could define a conversion function in a module and your transpiler could render the conversion as a call to that function.

    Take the following:-
    Code:
        Public Class Person
            Public Sub New(firstName As String, lastName As String)
                Me.FirstName = firstName
                Me.LastName = lastName
            End Sub
    
            Public Property FirstName As String
            Public Property LastName As String
    
            Public Shared Narrowing Operator CType(ByVal p As Person) As String
                Return $"{p.FirstName} {p.LastName}"
            End Operator
        End Class
    The above is a VB.Net class that has the CType operator overloaded. It defines a conversion from Person to String to be used like this:-
    Code:
            Dim Nick As New Person("Nick", "Logan")
    
            Dim s As String = CType(Nick, String)
    
            Debug.WriteLine(s)
    Which outputs this:-
    Code:
    Nick Logan
    VB6 doesn't have a CType operator and even if it did, the language doesn't support operator overloading. However, you can define the Person class like this:-
    Code:
    '==============================================
    'Person.cls
    '==============================================
    Public FirstName As String
    Public LastName As String
    And then you generate a conversion function in a separate module like this:-
    Code:
    '==============================================
    'Conversions.bas
    '==============================================
    Public Function Conv_Person_To_String(ByVal p As Person) As String
        Conv_Person_To_String = p.FirstName & " " & p.LastName
    End Function
    Which you then use like this:-
    Code:
        Dim Nick As New Person
        Dim s As String
        
        Nick.FirstName = "Nick"
        Nick.LastName = "Logan"
        
        s = Conversions.Conv_Person_To_String(Nick)
        
        Debug.Print s
    This is how an overloadable operator like CType could be transpiled from VB.Net to VB6.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  4. #4

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Generic type conversion function CType

    Hi baka, Niya

    When I use generic CType functions, I can achieve the following effects:
    Code:
    Public Sub DoTest()
        Set TheValue = CType(SourceValue, "MyClass")
        If IsEmptyOrNothing(TheValue) Then Exit Sub
    
        TheValue2 = CType(SourceValue2, vbString)
        If IsEmptyOrNothing(TheValue2) Then Exit Sub
    
        TheValue3 = CType(SourceValue3, vbArray)
        If IsEmptyOrNothing(TheValue3) Then Exit Sub
    
        TheValue4 = CType(SourceValue4, "Guid")
        If IsEmptyOrNothing(TheValue4) Then Exit Sub
        
        TheValue5 = CType(SourceValue5, "BigInt")
        If IsEmptyOrNothing(TheValue5) Then Exit Sub
    
        '--- DoSomething ---
    
    End Sub
    Last edited by SearchingDataOnly; Jun 16th, 2022 at 08:37 AM.

  5. #5

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Generic type conversion function CType

    Quote Originally Posted by Niya View Post
    The CType operator in VB.Net is actually dependent on the operator itself being overloaded on the type being converted. Unfortunately, VB6 doesn't have operator overloading.

    If this is for your transpiler. You could translate conversions between primitive types like Integers, Strings etc using normal VB6 conversion functions like CInt and CStr. For classes, you could define a conversion function in a module and your transpiler could render the conversion as a call to that function.

    Take the following:-
    Code:
        Public Class Person
            Public Sub New(firstName As String, lastName As String)
                Me.FirstName = firstName
                Me.LastName = lastName
            End Sub
    
            Public Property FirstName As String
            Public Property LastName As String
    
            Public Shared Narrowing Operator CType(ByVal p As Person) As String
                Return $"{p.FirstName} {p.LastName}"
            End Operator
        End Class
    The above is a VB.Net class that has the CType operator overloaded. It defines a conversion from Person to String to be used like this:-
    Code:
            Dim Nick As New Person("Nick", "Logan")
    
            Dim s As String = CType(Nick, String)
    
            Debug.WriteLine(s)
    Which outputs this:-
    Code:
    Nick Logan
    VB6 doesn't have a CType operator and even if it did, the language doesn't support operator overloading. However, you can define the Person class like this:-
    Code:
    '==============================================
    'Person.cls
    '==============================================
    Public FirstName As String
    Public LastName As String
    And then you generate a conversion function in a separate module like this:-
    Code:
    '==============================================
    'Conversions.bas
    '==============================================
    Public Function Conv_Person_To_String(ByVal p As Person) As String
        Conv_Person_To_String = p.FirstName & " " & p.LastName
    End Function
    Which you then use like this:-
    Code:
        Dim Nick As New Person
        Dim s As String
        
        Nick.FirstName = "Nick"
        Nick.LastName = "Logan"
        
        s = Conversions.Conv_Person_To_String(Nick)
        
        Debug.Print s
    This is how an overloadable operator like CType could be transpiled from VB.Net to VB6.
    Since you are proficient in both dotNET and VB6, your code always inspires me a lot, thank you, Niya.

    I want to simulate C#'s type system (reflection), but I looked at the source code of Type.cs and RuntimeType.cs of C#, and it seems very difficult to simulate C#'s reflection.

  6. #6
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    Quote Originally Posted by SearchingDataOnly View Post
    and it seems very difficult to simulate C#'s reflection.
    Reflection would probably one of the easiest things to implement. All you're doing is selectively exposing the data created by the parser. You could just use nodes from the AST to build metadata about classes, methods, and whatever else you want. You then use then expose this metadata through classes and methods in your language. It would probably be very tedious to actually implement but the underlying concept is very simple.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  7. #7
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,910

    Re: Generic type conversion function CType

    Not sure if this is what y'all are talking about, but: see here.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  8. #8
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    Quote Originally Posted by Elroy View Post
    Not sure if this is what y'all are talking about, but: see here.
    Something like that, however reflection in .Net and other modern languages can do typically do far more than just instantiate objects dynamically at runtime. Reflection allows you to enumerate over elements in the program itself. You can enumerate over types like classes and structs, get information about their methods like their names, parameters, return type etc. You can get information about classes themselves like if they are a subtype of another type, what interfaces they implement etc. You can also use it to create objects and call their methods. Reflections basically allows you to treat your program as a graph of objects from within itself.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  9. #9
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,910

    Re: Generic type conversion function CType

    Yes, that would be nice. I've often wanted an enumeration of the instantiated objects I have (without all the work of tracking them in the Initialize events.

    Sort of like the Controls (or Forms) collection, but project wide.
    Last edited by Elroy; Jun 16th, 2022 at 11:27 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  10. #10
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    Quote Originally Posted by Elroy View Post
    Yes, that would be nice. I've often wanted an enumeration of the instantiated objects I have (without all the work of tracking them in the Initialize events.
    I think you misunderstand. No language I know allows explicit access to live objects. Reflection allows you access to the information about your program as defined by its source code:-

    For example lets take these classes in VB.Net:-
    Code:
        Private Class Class1
            Public Sub PrintValue()
                Debug.WriteLine(23)
            End Sub
        End Class
    
        Private Class Class2
            Public Sub PrintValue()
                Debug.WriteLine(45)
            End Sub
        End Class
    
        Private Class Class3
            Public Sub PrintValue()
                Debug.WriteLine("Hello world.")
            End Sub
        End Class
    You could instantiate and call their methods like this:-
    Code:
        Private Sub DoItNormally()
            Dim c1 As New Class1
            Dim c2 As New Class2
            Dim c3 As New Class3
    
            c1.PrintValue()
            c2.PrintValue()
            c3.PrintValue()
    
        End Sub
    That's pretty standard. It's just the normal way we create object and call their methods. However, this is fixed at compile time. With reflection, you can do this at runtime like this:-
    Code:
        Private Sub DoItUsingReflection()
    
            Dim asm = Assembly.GetExecutingAssembly
    
            'Enumerate all types in the assembly
            For Each t As Type In asm.GetTypes
    
                'If the current type is a class or structure whose
                'declaration is nested inside this Form class
                If t.DeclaringType Is Me.GetType Then
    
                    'Look for a method called PrintValue on the class
                    Dim m = t.GetMethod("PrintValue")
    
                    'If the method exists then....
                    If m IsNot Nothing Then
    
                        'Create an instance of the class
                        Dim c As Object = Activator.CreateInstance(t)
    
                        'Call the PrintValue method on the object
                        m.Invoke(c, {})
                    End If
                End If
            Next
    
        End Sub
    The above does the same thing but at runtime instead. I told it to search for all types nested inside that Form class, instantiate them and call their PrintValue method. If I were to add other nested classes to the form with PrintValue methods afterwards and re-compile, I wouldn't have to change that function at all because the new class would be enumerated at runtime.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  11. #11
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    Quote Originally Posted by SearchingDataOnly View Post
    Hi baka, Niya

    When I use generic CType functions, I can achieve the following effects:
    Code:
    Public Sub DoTest()
        Set TheValue = CType(SourceValue, "MyClass")
        If IsEmptyOrNothing(TheValue) Then Exit Sub
    
        TheValue2 = CType(SourceValue2, vbString)
        If IsEmptyOrNothing(TheValue2) Then Exit Sub
    
        TheValue3 = CType(SourceValue3, vbArray)
        If IsEmptyOrNothing(TheValue3) Then Exit Sub
    
        TheValue4 = CType(SourceValue4, "Guid")
        If IsEmptyOrNothing(TheValue4) Then Exit Sub
        
        TheValue5 = CType(SourceValue5, "BigInt")
        If IsEmptyOrNothing(TheValue5) Then Exit Sub
    
        '--- DoSomething ---
    
    End Sub
    Oh I missed this one. CType actually throws an exception if it cannot perform a conversion. You're actually thinking of the TryCast which works similarly to CType but returns Nothing if it fails to perform a conversion. TryCast only works where there is an inheritance relationship though so in that sense its more limited than CType.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  12. #12
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,892

    Re: Generic type conversion function CType

    I was recently in a big debate about generics and reflection at the tB GitHub discussion board. Try as I might, I don't see generics & reflection as an improvement over the COM contractual approach.

    For example, why not something like this:

    Code:
    Dim t As Object
    
    For Each t in SomeCollectionOfVariousTypes
    	If TypeOf t Is IPrintValue Then
    		t.PrintValue
    	End If
    Next t
    Or event better in a new VB/tB:

    Code:
    For Each t Of IMyDesiredInterface In SomeCollectionOfVariousTypes
    	t.PrintValue
    Next

    Why all the ceremony of this?

    Code:
        Private Sub DoItUsingReflection()
    
            Dim asm = Assembly.GetExecutingAssembly
    
            'Enumerate all types in the assembly
            For Each t As Type In asm.GetTypes
    
                'If the current type is a class or structure whose
                'declaration is nested inside this Form class
                If t.DeclaringType Is Me.GetType Then
    
                    'Look for a method called PrintValue on the class
                    Dim m = t.GetMethod("PrintValue")
    
                    'If the method exists then....
                    If m IsNot Nothing Then
    
                        'Create an instance of the class
                        Dim c As Object = Activator.CreateInstance(t)
    
                        'Call the PrintValue method on the object
                        m.Invoke(c, {})
                    End If
                End If
            Next
    
        End Sub
    Last edited by jpbro; Jun 16th, 2022 at 11:40 PM.

  13. #13
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    Quote Originally Posted by jpbro View Post
    I was recently in a big debate about generics and reflection at the tB GitHub discussion board. Try as I might, I don't see generics & reflection as an improvement over the COM contractual approach.
    All of my years going back and forth in VB6 vs VB.Net discussions hasn't convinced anyone who's mind was already made up so I'm not even going to pretend I can convince you. There is just no way I could relate you why it's a massive improvement in just one sentence or even a single paragraph. All I can tell you is that those of us that have spent years enjoying these features know why we love them and why it can be extremely painful using a language without them. I can't speak for all of "us" on this particular point but speaking for myself alone, you couldn't pay me to ever seriously write VB6 applications ever again. I don't mind doing stuff for the forums here and there, maybe even a CodeBank submission from time to time but there is nothing in the world that could motivate me to ever seriously go back to VB6. When you get used to the features of modern languages like generics, reflection and all the others I've mentioned in the past, it is damn near impossible to live without them. You actually feel it. It's very very suffocating.

    Quote Originally Posted by jpbro View Post
    For example, why not something like this:

    Code:
    Dim t As Object
    
    For Each t in SomeCollectionOfVariousTypes
    	If TypeOf t Is IPrintValue Then
    		t.PrintValue
    	End If
    Next t
    Or event better in a new VB/tB:

    Code:
    For Each t Of IMyDesiredInterface In SomeCollectionOfVariousTypes
    	t.PrintValue
    Next
    That is not reflection. That code is just normal everyday collection enumeration that could be found in any language.

    Reflection is about your program looking into itself and seeing itself. It can see it's own classes, interfaces, methods etc. Here's an exercise that could perhaps make it clearer what reflection is. Write a function in VB6, any function. Now at runtime I want you to have your program find this function and tell you how many parameters it has, and what the type of each parameter is, and what the return type of the function is. You should find that this is impossible in VB6. However, you can do it in VB.Net, C# and I believe even Python can do this. Here's what the above exercise would look like in VB.Net:-
    Code:
    Imports System.Reflection
    Imports System.Text
    
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Debug.WriteLine(GetFuncInfo("JustSomeFunc"))
        End Sub
    
        Private Function GetFuncInfo(ByVal funcName As String) As String
    
            Dim sb As New StringBuilder
    
            Dim method = (From t In Assembly.GetExecutingAssembly.GetTypes
                          Let m = t.GetMethod(funcName, BindingFlags.NonPublic Or BindingFlags.Instance)
                          Where m IsNot Nothing
                          Select m).FirstOrDefault
    
            If method IsNot Nothing Then
    
                sb.AppendLine($"Method name : {method.Name}")
                sb.AppendLine($"Number of parameters : {method.GetParameters.Length.ToString}")
                sb.AppendLine($"Method return type : {method.ReturnType.Name}")
    
                For Each p In method.GetParameters
                    sb.AppendLine($"{vbTab} Parameter name = '{p.Name}', Parameter type = {p.ParameterType.Name}")
                Next
    
            End If
    
            Return sb.ToString
        End Function
    
        'Just an empty sample function for reflection to find.
        Private Function JustSomeFunc(ByVal name As String, ByVal age As Integer, ByVal money As Double) As String()
    
        End Function
    
    
    End Class
    The above code would output this:-
    Code:
    Method name : JustSomeFunc
    Number of parameters : 3
    Method return type : String[]
    	 Parameter name = 'name', Parameter type = String
    	 Parameter name = 'age', Parameter type = Int32
    	 Parameter name = 'money', Parameter type = Double
    The above code demonstrates true reflection. The program was able to look inside itself, find the JustSomeFunc function and print details about it at runtime. You could even call it if you want. If I wanted, I could enumerate over every function and sub in the entire program and print it out:-
    Code:
    Imports System.Reflection
    Imports System.Text
    
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            For Each t In Assembly.GetExecutingAssembly.GetTypes
                For Each m In t.GetMethods(BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.DeclaredOnly)
                    Debug.WriteLine(GetInfo(m))
                Next
            Next
        End Sub
    
        Private Function GetInfo(ByVal m As MethodInfo) As String
            Dim sb As New StringBuilder
    
            sb.AppendLine($"Method name : {m.Name}")
            sb.AppendLine($"Number of parameters : {m.GetParameters.Length.ToString}")
            sb.AppendLine($"Method return type : {m.ReturnType.Name}")
    
            For Each p In m.GetParameters
                sb.AppendLine($"{vbTab} Parameter name = '{p.Name}', Parameter type = {p.ParameterType.Name}")
            Next
            Return sb.ToString
        End Function
    
    End Class
    The above outputs this:-
    Code:
    Method name : OnCreateMainForm
    Number of parameters : 0
    Method return type : Void
    
    Method name : Form1_Load
    Number of parameters : 2
    Method return type : Void
    	 Parameter name = 'sender', Parameter type = Object
    	 Parameter name = 'e', Parameter type = EventArgs
    
    Method name : GetInfo
    Number of parameters : 1
    Method return type : String
    	 Parameter name = 'm', Parameter type = MethodInfo
    
    Method name : Dispose
    Number of parameters : 1
    Method return type : Void
    	 Parameter name = 'disposing', Parameter type = Boolean
    
    Method name : InitializeComponent
    Number of parameters : 0
    Method return type : Void
    
    Method name : Dispose__Instance__
    Number of parameters : 1
    Method return type : Void
    	 Parameter name = 'instance', Parameter type = T&
    
    Method name : GetType
    Number of parameters : 0
    Method return type : Type
    
    Method name : GetType
    Number of parameters : 0
    Method return type : Type
    
    Method name : Dispose__Instance__
    Number of parameters : 1
    Method return type : Void
    	 Parameter name = 'instance', Parameter type = T&
    
    Method name : get_GetInstance
    Number of parameters : 0
    Method return type : T
    The above is selected information on every single sub and function declared in the program. If you look carefully, you will even see Form_Load sub and the GetInfo function there too.

    VB6 cannot do this because the compiler must build the metadata from the abstract syntax tree its parser produces. Now you might be able to kinda fake this in VB6 if you can access COM IDLs but from what I understand, it was never designed with this intent so it will take some wizardry to do it. Even so, a COM IDL will never have anywhere near the amount of information that an AST does. It will still be limited.
    Last edited by Niya; Jun 17th, 2022 at 01:45 AM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  14. #14
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    BTW where was this generics/reflection discussion? I don't see anything of the sort on the GitHub page.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  15. #15

  16. #16
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    Quote Originally Posted by The trick View Post
    You can get all the classes, types, enums for public project types in vb6. Each public project contains a tlb with types descriptions.
    I guessed it might be possible which is why I said this:-
    Quote Originally Posted by Niya View Post
    Now you might be able to kinda fake this in VB6 if you can access COM IDLs but from what I understand, it was never designed with this intent so it will take some wizardry to do it. Even so, a COM IDL will never have anywhere near the amount of information that an AST does. It will still be limited.
    Also, could you also enumerate private UDTs, private methods on classes and private fields on classes? Can you also call public and private methods on classes through reflective means? I'm not being sarcastic or anything. I'm genuinely asking.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  17. #17

  18. #18
    Addicted Member
    Join Date
    Oct 2011
    Posts
    179

    Re: Generic type conversion function CType

    Quote Originally Posted by Niya View Post
    Also, could you also enumerate private UDTs, private methods on classes and private fields on classes? Can you also call public and private methods on classes through reflective means? I'm not being sarcastic or anything. I'm genuinely asking.
    Private's have a pointer, not a name.

  19. #19
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    Quote Originally Posted by argen View Post
    Private's have a pointer, not a name.
    We're not talking about looking for live data at runtime, we're talking program data as in data about the program itself like defined classes, methods etc, things that were written by the programmer.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  20. #20
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    Quote Originally Posted by The trick View Post
    I'll answer later because I'm on the road.
    Okay.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  21. #21
    Addicted Member
    Join Date
    Oct 2011
    Posts
    179

    Re: Generic type conversion function CType

    Quote Originally Posted by Niya View Post
    We're not talking about looking for live data at runtime, we're talking program data as in data about the program itself like defined classes, methods etc, things that were written by the programmer.
    But for reflection you need the name, and there is no name for private definitions, just a pointer.

  22. #22

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Generic type conversion function CType

    Quote Originally Posted by Elroy View Post
    Not sure if this is what y'all are talking about, but: see here.
    Hi Elroy,

    Your modNameBasedObjectFactory is very useful.

    We know that we can use "TypeOf MyVar Is Class2" to determine whether MyVar is Class2, but I'd like to know if it is possible to achieve a similar "TypeOf MyVar Is Class2" effect by the class name "Class2". E.g:

    Class1.cls
    Code:
    Option Explicit
    
    Implements Class2
    
    Public Name As String
    
    Private m_nVersion As Long
    
    Public Sub ChangeName()
        m_nVersion = m_nVersion + 1
        Name = Name & "_" + m_nVersion
    End Sub
    
    Private Sub Class2_ChangeName()
        Me.ChangeName
    End Sub
    Class2.cls
    Code:
    Option Explicit
    
    Public Sub ChangeName()
    
    End Sub
    Form1.frm
    Code:
    Option Explicit
    
    Private Sub Form_Load()
        Dim var As Variant
        
        var = CType(GetTestResult(), "Class2")
        
        If Not IsEmptyOrNothing(var) Then
            MsgBox "var is Class2"
        Else
            MsgBox "var is not Class2"
        End If
        
    End Sub
    
    Private Function CType(var As Variant, sClassName As String) As Variant
    
    End Function
    
    Private Function GetTestResult() As Variant
        Dim cls As Class1
        Set cls = New Class1
        
        Set GetTestResult = cls
    End Function
    
    Private Function IsEmptyOrNothing(var) As Boolean
        If IsEmpty(var) = True Then
            IsEmptyOrNothing = True
            
        ElseIf IsObject(var) = True Then
            If var Is Nothing Then
                IsEmptyOrNothing = True
            End If
            
        ElseIf IsArray(var) = True Then
            If ArrIsNull(var) = True Then
                IsEmptyOrNothing = True
            End If
            
        End If
        
    End Function
    
    Private Function ArrIsNull(var) As Boolean
    
    End Function
    Attached Files Attached Files
    Last edited by SearchingDataOnly; Jun 18th, 2022 at 09:25 AM.

  23. #23

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Generic type conversion function CType

    Quote Originally Posted by Niya View Post
    Something like that, however reflection in .Net and other modern languages can do typically do far more than just instantiate objects dynamically at runtime. Reflection allows you to enumerate over elements in the program itself. You can enumerate over types like classes and structs, get information about their methods like their names, parameters, return type etc. You can get information about classes themselves like if they are a subtype of another type, what interfaces they implement etc. You can also use it to create objects and call their methods. Reflections basically allows you to treat your program as a graph of objects from within itself.
    I want to get C#-like reflection functionality in VB6.

    Quote Originally Posted by Niya View Post
    With reflection, you can do this at runtime like this:-
    Code:
        Private Sub DoItUsingReflection()
    
            Dim asm = Assembly.GetExecutingAssembly
    
            'Enumerate all types in the assembly
            For Each t As Type In asm.GetTypes
    
                'If the current type is a class or structure whose
                'declaration is nested inside this Form class
                If t.DeclaringType Is Me.GetType Then
    
                    'Look for a method called PrintValue on the class
                    Dim m = t.GetMethod("PrintValue")
    
                    'If the method exists then....
                    If m IsNot Nothing Then
    
                        'Create an instance of the class
                        Dim c As Object = Activator.CreateInstance(t)
    
                        'Call the PrintValue method on the object
                        m.Invoke(c, {})
                    End If
                End If
            Next
    
        End Sub
    The above does the same thing but at runtime instead. I told it to search for all types nested inside that Form class, instantiate them and call their PrintValue method. If I were to add other nested classes to the form with PrintValue methods afterwards and re-compile, I wouldn't have to change that function at all because the new class would be enumerated at runtime.
    Yes, that's exactly what I want.
    Last edited by SearchingDataOnly; Jun 18th, 2022 at 09:41 AM.

  24. #24

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Generic type conversion function CType

    Quote Originally Posted by Niya View Post
    Oh I missed this one. CType actually throws an exception if it cannot perform a conversion. You're actually thinking of the TryCast which works similarly to CType but returns Nothing if it fails to perform a conversion. TryCast only works where there is an inheritance relationship though so in that sense its more limited than CType.
    Yes, I know that in VB.NET, there is a difference between CType, TryCast and DirectCast. But I want to implement the functionality of those three functions in my CType.

    Quote Originally Posted by The trick View Post
    You can get all the classes, types, enums for public project types in vb6. Each public project contains a tlb with types descriptions.
    Could you give some specific examples? Thanks.
    Last edited by SearchingDataOnly; Jun 18th, 2022 at 09:51 AM.

  25. #25

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Generic type conversion function CType

    Quote Originally Posted by jpbro View Post
    I was recently in a big debate about generics and reflection at the tB GitHub discussion board. Try as I might, I don't see generics & reflection as an improvement over the COM contractual approach.
    Hi jpbro,

    Your point makes sense. Generics make C# and VB.NET expressive, but generics also increase the complexity of the language. I've been looking for a solution that reduces the complexity of the language while still implementing most of the features of generics.

    RC6.ArrayList provides another generic solution, for example:

    Code:
    Dim AL As cArrayList
    
    Set AL = New_c.ArrayList(vbString)
    That is to say, when variables are declared, there is no generic, but when creating an object, generic is used, but this solution also has some limitations, that is, we cannot use generics in function parameters and function return values, for example:
    Code:
    Public Function MyFunc(Params As List(Of String)) As List(Of MyClass)
    
    End Function
    Although I can partially implement some generic features by providing ListOfString, ListOfLong, ListOfObject, however, I cannot implement generics for all UDTs and classes such as ListOfMyClass1, ListOfMyClass2 ...
    Last edited by SearchingDataOnly; Jun 18th, 2022 at 10:23 AM.

  26. #26
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: Generic type conversion function CType

    Quote Originally Posted by SearchingDataOnly View Post
    Your point makes sense. Generics make C# and VB.NET expressive, but generics also increase the complexity of the language. I've been looking for a solution that reduces the complexity of the language while still implementing most of the features of generics.
    Dynamic typing achieves the same goals as generics while being much simpler to use and understand. However, you give up something big which is safety. Dynamically typed languages are error prone.

    The thing one has to realize about choosing a programming language is that it's all about trade-offs. Even in cases where one language might be more powerful than another, you're still trading. You're never going to get one language that is better than another while still having everything the lesser language has. You're always going to give something up. For example, moving from VB6 to VB.Net you are giving up simplicity for flexibility. Moving from Assembly to C, you're giving up power for terseness.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  27. #27

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,844

    Re: Generic type conversion function CType

    Quote Originally Posted by Niya View Post
    Dynamic typing achieves the same goals as generics while being much simpler to use and understand. However, you give up something big which is safety. Dynamically typed languages are error prone.
    Maybe we can use a contract-class like dotnet's to reduce errors caused by dynamic typing, so as to achieve a balance between simplicity and safety.

    TypeScript uses "dynamic interfaces" to improve the safety of dynamic typing. Of course, we can't seem to use "dynamic interfaces" in VB6
    Last edited by SearchingDataOnly; Jun 21st, 2022 at 09:27 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width