vb.net reflection vs. late binding? - vb.net

What should be more proper or what is recommended to use in VB.NET from either reflection vs. late binding:
'Type can be various objects that have a common property for sure.'
Dim type = sender.GetType()
Dim prop = type.GetProperty("Text", 20)
Dim value = property.GetValue(sender, Nothing)
versus:
Dim value = sender.Text

Under the covers they are both doing the same thing (relatively speaking). VB.NET's late-binding feature is done via assembly metadata queries at runtime which is exactly what reflection is all about.
One of the benefits to your first approach is that you have an opportunity to handle errors in a more finely-grained manner.

Isn't sender.Text always a string though? So the type of value can be inferred at compile time, making the latter an example of early binding?

If you do use late binding, you can put the method that extracts the properties into a partial class with Option Explicit = Off. That way, you still have type checking in the rest of your code.

Related

Do I understand not using getters and setters correctly

After reading this piece by Yegor about not using getters and setters, it sounds like something that makes sense to me.
Please note this question is not about whether doing it is better/worst, only if I am implementing it correctly
I was wondering in the following two examples in VBA, if I understand the concept correctly, and if I am applying it correctly.
The standard way would be:
Private userName As String
Public Property Get Name() As String
Name = userName
End Property
Public Property Let Name(rData As String)
userName = rData
End Property
It looks to me his way would be something like this:
Private userName As String
Public Function returnName() As String
returnName = userName
End Function
Public Function giveNewName(newName As String) As String
userName = newName
End Function
From what I understand from the two examples above is that if I wanted to change the format of userName (lets say return it in all-caps), then I can do this with the second method without changing the name of the method that gives the name through - I can just let returnName point to a userNameCaps property. The rest of my code in my program can still stay the same and point to the method userName.
But if I want to do this with the first example, I can make a new property, but then have to change my code everywhere in the program as well to point to the new property... is that correct?
In other words, in the first example the API gets info from a property, and in the second example the API gets info from a method.
Your 2nd snippet is neither idiomatic nor equivalent. That article you link to, is about Java, a language which has no concept whatsoever of object properties - getFoo/setFoo is a mere convention in Java.
In VBA this:
Private userName As String
Public Property Get Name() As String
Name = userName
End Property
Public Property Let Name(rData As String)
userName = rData
End Property
Is ultimately equivalent to this:
Public UserName As String
Not convinced? Add such a public field to a class module, say, Class1. Then add a new class module and add this:
Implements Class1
The compiler will force you to implement a Property Get and a Property Let member, so that the Class1 interface contract can be fulfilled.
So why bother with properties then? Properties are a tool, to help with encapsulation.
Option Explicit
Private Type TSomething
Foo As Long
End Type
Private this As TSomething
Public Property Get Foo() As Long
Foo = this.Foo
End Property
Public Property Let Foo(ByVal value As Long)
If value <= 0 Then Err.Raise 5
this.Foo = value
End Property
Now if you try to assign Foo with a negative value, you'll get a runtime error: the property is encapsulating an internal state that only the class knows and is able to mutate: calling code doesn't see or know about the encapsulated value - all it knows is that Foo is a read/write property. The validation logic in the "setter" ensures the object is in a consistent state at all times.
If you want to break down a property into methods, then you need a Function for the getter, and assignment would be a Sub not a Function. In fact, Rubberduck would tell you that there's a problem with the return value of giveNewName being never assigned: that's a much worse code smell than "OMG you're using properties!".
Functions return a value. Subs/methods do something - in the case of an object/class, that something might imply mutating internal state.
But by avoiding Property Let just because some Java guy said getters & setters are evil, you're just making your VBA API more cluttered than it needs to be - because VBA understands properties, and Java does not. C# and VB.NET do however, so if anything the principles of these languages would be much more readily applicable to VBA than Java's, at least with regards to properties. See Property vs Method.
FWIW public member names in VB would be PascalCase by convention. camelCase public member names are a Java thing. Notice how everything in the standard libraries starts with a Capital first letter?
It seems to me that you've just given the property accessors new names. They are functionally identical.
I think the idea of not using getters/setters implies that you don't try to externally modify an object's state - because if you do, the object is not much more than a user-defined type, a simple collection of data. Objects/Classes should be defined by their behavior. The data they contain should only be there to enable/support that behavior.
That means you don't tell the object how it has to be or what data you want it to hold. You tell it what you want it to do or what is happening to it. The object itself then decides how to modify its state.
To me it seems your example class is a little too simple to work as an example. It's not clear what the intended purpose is: Currently you'd probably better off just using a variable UserName instead.
Have a look at this answer to a related question - I think it provides a good example.
Regarding your edit:
From what I understand from the two examples above is that if I wanted
to change the format of userName (lets say return it in all-caps),
then I can do this with the second method without changing the name of
the method that gives the name through - I can just let returnName
point to a userNameCaps property. The rest of my code in my program
can still stay the same and point to the method iserName.
But if I want to do this with the first example, I can make a new
property, but then have to change my code everywhere in the program as
well to point to the new property... is that correct?
Actually, what you're describing here, is possible in both approaches. You can have a property
Public Property Get Name() As String
' possibly more code here...
Name = UCase(UserName)
End Property
or an equivalent function
Public Function Name() As String
' possibly more code here...
Name = UCase(UserName)
End Function
As long as you only change the property/function body, no external code needs to be adapted. Keep the property's/function's signature (the first line, including the Public statement, its name, its type and the order and type of its parameters) unchanged and you should not need to change anything outside the class to accommodate.
The Java article is making some sort of philosophic design stance that is not limited to Java: The general advise is to severely limit any details on how a class is implemented to avoid making one's code harder to maintain. Putting such advice into VBA terms isn't irrelevant.
Microsoft popularized the idea of a Property that is in fact a method (or two) which masquerade as a field (i.e. any garden-variety variable). It is a neat-and-tidy way to package up a getter and setter together. Beyond that, really, behind the scenes it's still just a set of functions or subroutines that perform as accessors for your class.
Understand that VBA does not do classes, but it does do interfaces. That's what a "Class Module" is: An interface to an (anonymous) class. When you say Dim o As New MyClassModule, VBA calls some factory function which returns an instance of the class that goes with MyClassModule. From that point, o references the interface (which in turn is wired into the instance). As #Mathieu Guindon has demonstrated, Public UserName As String inside a class module really becomes a Property behind the scenes anyway. Why? Because a Class Module is an interface, and an interface is a set of (pointers to) functions and subroutines.
As for the philosophic design stance, the really big idea here is not to make too many promises. If UserName is a String, it must always remain a String. Furthermore, it must always be available - you cannot remove it from future versions of your class! UserName might not be the best example here (afterall, why wouldn't a String cover all needs? for what reason might UserName become superfluous?). But it does happen that what seemed like a good idea at the time the class was being made turns into a big goof. Imagine a Public TwiddlePuff As Integer (or instead getTwiddlePuff() As Integer and setTwiddlePuff(value As Integer)) only to find out (much later on!) that Integer isn't sufficient anymore, maybe it should have been Long. Or maybe a Double. If you try to change TwiddlePuff now, anything compiled back when it was Integer will likely break. So maybe people making new code will be fine, and maybe it's mostly the folks who still need to use some of the old code who are now stuck with a problem.
And what if TwiddlePuff turned out to be a really big design mistake, that it should not have been there in the first place? Well, removing it brings its own set of headaches. If TwiddlePuff was used at all elsewhere, that means some folks may have a big refactoring job on their hands. And that might not be the worst of it - if your code compiles to native binaries especially, that makes for a really big mess, since an interface is about a set of function pointers layed out and ordered in a very specific way.
Too reiterate, do not make too many promises. Think through on what you will share with others. Properties-getters-setters-accessors are okay, but must be used thoughtfully and sparingly. All of that above is important if what you are making is code that you are going to share with others, and others will take it and use it as part of a larger system of code, and it may be that these others intend to share their larger systems of code with yet even more people who will use that in their even larger systems of code.
That right there is probably why hiding implementation details to the greatest extent possible is regarded as fundamental to object oriented programming.

Late Binding in VB

From what I have read so far, late binding is defining a variable as Object and then assigning it to the actual object later which is actually done at run time. I don't understand the point to that. Maybe this is the Java in me, but doesn't that limit the functionality to what is just in Object? It is like saying, "I want the potential of the extra stuff, but I don't want to have access to it." Is there an actual purpose for late binding in VB, or Java for that matter, that I'm overlooking?
You have it backwards. By using early binding you are limiting yourself to just the members of the type of the variable. With Option Strict On, a variable declared as type Object will only allow you access to members of type Object, regardless of the type of the actually object it refers to. With Option Strict Off, you can access a member of any name on a variable of type Object and the compiler won't complain. It's only at run time that any type checking is done so, as long as the actual object assigned to the variable has a member with that name, the code will run.
Probably the most common use for late binding is Office Automation. There are other options now but, in the past, if you referenced an Office library and used the specific types it contained, facilitating early binding, then you were limited to that specific version of Office. In order to support multiple versions, you had to forgo the reference, declare all your variables as type Object and use late binding. As long as the version of Office present at run time included the specified members on the objects used, the code would run without issue.
By the way, late binding doesn't require using type Object, although it is probably the most common. It just means that the reference is a less derived type than the object and you use a member of the object's type that the reference's type doesn't have, e.g. you use type Control and then use a member specific to type Button.
What I seen - some early .NET adapters-developers were doing is - they were using late binding instead on interfaces. They would declare two or more types
Public Class Handler1
Public Sub Execute()
' do something
End Sub
End Class
Public Class Handler2
Public Sub Execute()
' do something else
End Sub
End Class
And they would stick this thing into session object
If someting = 1 Then
Session("Handler") = New Handler1()
Else
Session("Handler") = New Handler2()
End If
And then, to process something they would do
Session("Handler").Execute()
There we go. This is not pretty or smart. But that was instead of proper programming like this (Imagine handlers implement IHandler interface with method Execute)
Dim h As IHandler = TryCast(Session("Handler"), IHandler)
If h IsNot Nothing Then
h.Execute()
End If
Here is where downfall of late binding starts: In the case of late binding, someone, somewhere, can rename a method Execute and compile code nicely. Release. And only then, at runtime, get a problem.
Late binding was good when we used to deal with interop and COM. Other than this, it is detrimental.

Parameter.GetType() - Does the type has to be known at compilation time?

is something like this possible - and if so how?
Public Sub CreateGenericList(ByVal SampleObject As Object)
Dim genericList as new List(Of SampleObject.GetType())
End Function
I want to create a class that is able to deserialize a given XML-file.
The XML-file contains serialized values of a custom type, which is unknown at compilation time.
I thought it might be possible to just initialize the class with a parameter SampleObject and to then get that SampleObject's type for all further progressing.
But it seems as if the type for all operations has to be known at compilation time?
Is there a way around it or can you explain the problem to me?
The code example above is just to illustrate my problem
Thanks for the help,
Janis
Edit: Your answers might allready have solved the problem, I will read more on the topics "reflection" and "generics" and keep you up to date if i make any progress. So thanks allot for the help.
For those still interested:
I was asked for the purpose of my question and will try to explain it as best i can.
Public Function ReadAllObjects() As List(Of myObjectType)
Dim result As New List(Of myObjectType)
Dim ObjectSerializer As New System.Xml.Serialization.XmlSerializer(result.GetType)
Dim FileReader As New System.IO.FileStream(My.Settings.XMLPath, System.IO.FileMode.Open)
result = TryCast(ObjectSerializer.Deserialize(FileReader), List(Of myObjectType))
FileReader.Close()
RaiseEvent ReadingFinished()
Return result
End Function
This pretty much sums up what I want to create: A EasyXmlHandling.dll for further use, which will be initialized with the currently used variable type.
It is then supposed to be able to write and read from/to an XML-File in a really easy way, by just calling "ReadAllObjects" (returns a List of myObjectType) or "AddObject(ByVal theNewObject)"... (more functions)
I got all that to work with a custom class as type, so i could now easily re-use the EasyXmlHandling-code by just replacing that type in the sourcecode with whatever new class i will want to use.
I though would prefer to just call the .dll with a sample object (or the type of it) and to have it do everything else automaticly.
I hope that was understandable, but neither my english nor my technical vocabulary are really good ;)
So thanks again for the help and for reading through this.
I will try to get it to work with all your previous answers and will update the topic when i make further progress.
No, that is not possible (at least, not without using reflection). The whole point of specifying the type in a generic list, or any other generic type, is so that the compiler can perform compile-time type checking. If you aren't specifying the type at compile-time, there is no benefit to it at all. Beyond there being no benefit, it's also simply not supported. If you don't know the type at compile time, you should just use Object instead, since that will work with objects of any type, for instance:
Dim myList As New List(Of Object)()
If you need a list, however, which only allows one type of item, but that type is unknown at compile time, that is possible to do, but you would probably need to create your own non-generic list class for something like that. As far as I know, there is no non-generic list class provided in the framework which restricts its items to a single specified type.
Update
Now that you've explained your reason for doing this, it's clear that generics are your solution. For instance, you could implement it as as generic function, like this:
Public Function ReadAllObjects(Of T)() As List(Of T)
Dim result As New List(Of T)
Dim ObjectSerializer As New System.Xml.Serialization.XmlSerializer(result.GetType)
Dim FileReader As New System.IO.FileStream(My.Settings.XMLPath, System.IO.FileMode.Open)
result = TryCast(ObjectSerializer.Deserialize(FileReader), List(Of T))
FileReader.Close()
RaiseEvent ReadingFinished()
Return result
End Function
Then, you could call it, like this, passing it which ever type you want:
Dim cars As New List(Of Car) = ReadAllObjects(Of Car)()
Dim boats As New List(Of Boat) = ReadAllObjects(Of Boat)()
As you can see, that is the whole purpose of generics. They are a very powerful tool when you any to keep your code type-specific, but still be able to re-use it with different types. Reflection, on the other-hand is not a good fit in this particular situation. Reflection is also very useful, but should always be considered an option of last resort. If there is another way to do it, without reflection, that's usually the better way.

Is there a way to find an object in an application?

Is there a way that I can parse through the objects of an application and determine if each one is TypeOf a particular form object? I have found no clear way getting a reference to forms that have already been opened. Complicating this further, it appears that not all Visual Basic commands are available to me when coding for an old PocketPC device.
You might want to have alook into Reflection. With this you can get all types of a NameSpace, then get all members of all class then do your compare. Since Reflection is used for bindings it might be available in your framework.
So this could be a start :
Dim MyAssembly = Reflection.Assembly.GetExecutingAssembly
Dim AllTypes = MyAssembly.GetTypes()
Dim AllClass = From x In AllTypes Where x.IsClass Select x

Converting Value Type of a Dictionary in VB.net

Public Class A
Public Class B : Inherits A
Dim DictA As Dictionary(Of Integer, A)
Dim DictB As New Dictionary(Of Integer, B)
DictA = DictB
This doesn't work, as the type can't be converted. Is this somehow possible?
No. You're running into the problem of generic variance, which isn't supported in .NET except in a few very particular ways.
Here's the reason: after your last line, you've got a single dictionary with two "views" onto it, effectively. Now imagine you wrote:
DictA.Add(1, New A())
(Apologies if my VB is slightly off.) That's inserted a "non-B" into the dictionary, but DictB thinks that all the values will be instances of B.
One of the main purposes of generics is to catch potential type failures at compile time rather than execution time - which means this code should fail to compile, which indeed it does precisely because of the lack of variance.
It's a bit counter-intuitive when you're used to normal inheritance, but it does make sense. A bunch of bananas isn't just a collection of fruit - it's a collection of bananas.
Java takes a somewhat different stance on this using wildcarding from the caller's side - it would let you see just the "adding" side of the dictionary for DictB, for instance, as anything you add to DictB would be fine in DictA. Java's generics are very different to .NET generics though...
This is a interesting, and quite complex aspect of Static type systems.
The terms you are looking for is Covariance and Contravariance.
The c# language will get this for certain sorts of operations on Generic types in 4.0 though in a somewhat limited form.
You have it to a certain degree already in the form of
object[] x = new string[1];
Which is allowed because arrays are treated covariantly, which means that you could then do the following:
x[0] = new object();
which would throw an Exception at runtime. Do you see how the same would apply to you Dictionaries...
The c# 4.0 spec is still non final so is subject to change but for some discussions and explanations see this question
Unfortunately not. This is a known absence of covariance/contravariance support. The CLR supports it, but the compilers for C# and VB.Net do not.
The next version of C# (4.0) actually does support it now, but not sure about vb.net.
Also, with System.Linq, one of the extension methods is Cast() which would allow you to cast from a collection of one type to another. However it will still return IEnumerable so you need to manipulate a little bit, but I think key-value types will be harder than collections with only one generic type.