My question is, when calling a generic method in vb I am used to having to state what type i am passing. Example 3. I am running VS 2012 and now I dont have to do this. Example 2. My question is when did this change, and how is this working(is the compiler reflecting the type to put in and letting me be lazy)?
Public function Foo(of T)(bar as T) As Boolean
return true
end function
Example 2
public sub TestFoo()
dim test as int = 0
Foo(test)
end sub
Example 3
public sub TestFoo()
dim test as int = 0
Foo(of int)(test)
end sub
The compiler simply infers what type to use. This feature was available when generics were introduced.
Example 2 and 3 still exist in VS2012, they are simply 2 different implementations. One is using a Generic declaration the other is not.
Here is a good example: Explain Generics in layman style in C#?
Related
I want my program to take a variable, and find letters A-Z. I have made this section of my program in a module to be shared between 2 different forms.
variables are passed from form1 and are processed by the module and then sent back again to form1. the problem is I think some sort of bug in the code but I cant identify it.
Public Function UPCASES(ByRef password1, points) As Boolean
Dim intersection As IEnumerable(Of Char)
intersection = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Intersect(password1)
'System.StackOverflowException error ^^^^^^^^^^^^^^^^^^^^^^^^^
If intersection.Count() = 1 Then
points = 5
Else
points = 0
End If
Return UPCASES(password1, points)
End Function
You are calling the method itself at the method end, that causes the StackOverflowException:
Return UPCASES(password1, points)
I guess this method should check if the password contains uppercase letters, then use:
Dim containsUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Intersect(password1).Any()
So no need to create a method just for this one-liner, if you need a method:
Public Function ContainsUpperCaseLetter(password1 As String) As Boolean
Return "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Intersect(password1).Any()
End Function
Side-note: you should change your default project settings to use Option Strict ON(Off is default unfortunately). Then you will be able to write much more safe, robust and performant code after you have learned a lot about .NET types because you have to fix the compiler errors.
Please see the code below:
Public Class Student
End Class
Public Class Undergraduate
Inherits Student
Public Sub Test(ByVal o As Object, ByVal s As Student)
o.Hello() 'Line 8
s.Hello() 'Line 9
End Sub
End Class
Line 8 throws an exception at runtime i.e. missing member exception. Line 9 produces a compile time error i.e. Hello is not a member of Student. Why doesn't line 8 throw a compile time exception.
Because o could be of type Student at runtime. Every class can be casted to Object.
The last time I used late binding was in C#. I have discovered that Visual Basic seems to be a bit of an exception as described here:
"
Visual Basic uses them whenever the variable is of type Object and the compiler directive "Option Strict Off" is in force
"
Source Wikipedia: http://en.wikipedia.org/wiki/Late_binding#Late_binding_in_.NET.
Public Class Student
Public Overridable Sub Test()
Console.WriteLine("Hello, I am a student.")
End Sub
End Class
Public Class Undergraduate
Inherits Student
Public Overrides Sub Test()
MyBase.Test ' skip this if this class COMPLETELY
' replaces the base class functionality
Console.WriteLine("...and I am an undergrad.")
End Sub
End Class
Dim a As New Student
Dim b As New Undergraduate
a.Test
b.Test
Output:
Hello, I am a student ' from a
Hello, I am a student ' from b's MyBase.Test
...and I am an undergrad. ' from b
Your question relates to late binding. By passing o as Object, the IDE cannot tell whether the Hello method is available on a given object. It might be and it might not be. If you have Option Strict On the default settings will not allow this to compile for just this reason. If you are sure you know what you are doing, you can customize the error to change Late Binding errors to warnings or even ignore them.
The restructured code may give a better view of using inherited classes to avoid needing to use late binding and because passing an object to itself is a little odd.
Because you forgot to turn Option Strict On.
Really, it's the first thing one should do when creating a new VB.NET project, and it's a really pitty that it isn't enabled by default.
A list of which compile-time checks are added with Option Strict On can be found on MSDN:
http://msdn.microsoft.com/en-us/library/zcd4xwzs.aspx
Specifically aimed at winforms development.
I suspect that the answer to this is probably No but S.O. has a nice way of introducing me to things I didn't know so I thought that I would ask anyway.
I have a class library with a number of defined methods therein. I know from personal experimentation that it is possible to get information about the application within which the class library is referenced. What I would like to know is whether it would be possible to get information about the value of a property of a control on a form when a routine on that form calls a method in my class library without passing a specific reference to that form as a parameter of the method in the class library?
So purely as an example (because it's the only thing I can think of off the top of my head). Is there a way that a message box (if it had been so designed to do so in the first place) could 'know' from which form a call to it had been made without that form being specifically referenced as a parameter of the message box in the first place?
Thanks for any insights you might have.
To address the example of the MessageBox, in many of the cases you can use the active form. You can retrieve it by using Form.ActiveForm. Of course, as regards the properties that you can request, you are limited to the properties provided by the Form or an interface that the Form implements and that the method in the other assembly also knows. To access other properties you can use Reflection, but this approach would neither be straightforward nor would it be clean.
In a more general scenario, you could provide the property value to the method as a parameter. If it is to complex to retrieve the value of the property and the value is not needed every time, you can provide a Func(Of TRESULT) to the method that retrieves the value like this (sample for an integer property):
Public Sub DoSomethingWithAPropertyValue(propValFunc As Func(Of Integer))
' Do something before
If propertyValueIsNeeded Then
Dim propVal = propValFunc()
End If
' Do something afterwards
End Sub
You call the method like this:
Public Sub SubInForm()
Dim x As New ClassInOtherAssembly()
x.DoSomethingWithAPropertyValue(Function() Me.IntegerProperty)
End Sub
I kind of question your intentions. There's no problem sending the information to a function or the constructor.
Instead of giving the information to the class, the class would ask for the information instead using an event.
Module Module1
Sub Main()
Dim t As New Test
AddHandler t.GetValue, AddressOf GetValue
t.ShowValue()
Console.ReadLine()
End Sub
Public Sub GetValue(ByRef retVal As Integer)
retVal = 123
End Sub
End Module
Class Test
Public Delegate Sub DelegateGetValue(ByRef retVal As Integer)
Public Event GetValue As DelegateGetValue
Public Sub ShowValue()
Dim val As Integer
RaiseEvent GetValue(val)
Console.WriteLine(val)
End Sub
End Class
Whats the difference between these two initialization methods for obj? I've seen both of these, but know know if there is an appropriate time to use one vs the other. I found this post which covers C#, but not sure if the same applies to VB.Net.
Public Class Class1
Sub New()
End Sub
Dim obj As New Object
End Class
vs
Public Class Class1
Sub New()
obj=New Object
End Sub
Dim obj As Object
End Class
My apologies ahead of time if this a duplicate.
In this case, there is no difference. The main difference would be if your constructor does other operations -
In that case, the inline initialization (Dim obj As New Object) will occur prior to any code inside the constructor. Putting the initialization in the constructor lets you choose the order of initialization.
Virtually nothing is different about these samples. In both cases you get the following order of operations
Constructor for Class1 is called
Base constructor (Object in this case) is called
Field obj is assigned a value
In all likely hood it results in identical IL being generated.
Your first version is "declarative". The advantages of it are:
It is easier to see how an field as initialized, as you don't have to look for it in the constructor.
If you have multiple constructors you don't need to repeat yourself.
Your first version is "imperative". The advantages of it are:
You control exactly when it gets created.
You can have different versions for each constructor.
I personally default to declarative style code whenever possible.
I'm sure there is an answer to this somewhere but I'm clearly using the wrong terminology in my searches, so I apologise in advance for this inevitably being a duplicate.
Take the function CType. Clearly I can cast (or at least try) a given object to a given reference type. The function will not work if trying to cast to a structure, i.e.
CType(myObject, Integer)
...will generate a compiler error. This I'm sure most often crops up when working with generics:
Public Function GetResults(Of T)() As T
Dim instance As T
Return CType(GetData(instance), T)
End Function
Public Function GetData(ByVal param As myClass) As myClass
'do stuff
Return param
End Function
Public Function GetData(byval param As Integer) As Integer
'do stuff
Return param
End Function
Public Function GetResults(ByVal param As Object) As Object
Throw New NotImplementedException
End Function
Probably not the best of examples but hopefully shows what I mean. The following will work:
Dim result = GetResult(Of myClass)
The following will fail on the CType
Dim result = GetResult(Of Integer)
I'm not a big fan of using exceptions/Try-Catch if logic can be applied, so although I could Try-Catch the CType, I'd rather find a way to route it through different code. I know with Generics I can use
Public Function GetResults(Of T As Structure) As T
What is the opposite? I want only reference types so that CType doesn't fail... I can't overload the T As Structure with a plain T because it considers them identical signatures, so surely there's a keyword I'm missing somewhere? ^^
Long question, probably only requries a one word answer (sorry)... Thanks in advance!
Public Function GetResults(Of T As Class) As T