In the function below, what is the meaning of the & character? I'm not aware how it's valid syntax or how this would be used normally.
Normally using &= together would do a concatenation and assignment, resulting in "Hello world". However in this "typo" the code actually compiles but the result is just an assignment of " world" to the MyStr variable. Also if you define MyStr in the function rather than at the class level, the result is that it will not compile and interprets the & as a Type Character and fails because MyStr is a string and not of type Long.
Public Class MyClassName
Private MyStr As String
Public Sub New()
End Sub
Public Function MyFunction() As String
MyStr = "Hello"
MyStr& = " World"
Return MyStr
End Function
End Class
Microsoft admits it's a bug in the compiler.
It is not going to be fixed because that would be a breaking change.
As you mention, the & is acting as a type character. Type characters are essentially just a shorthand for declaring the type of a variable. For example, you could use
dim value& = 100 rather than dim value as Long = 100
They are generally used when defining a value on the fly, such as when passing a value to a function:
dim result = funcThatTakesALong(100&)
You can also see in the link that you posted there are also type characters for integers (%), decimals (#), singles (!), doubles (#), and strings ($).
Edit: formatting
I think this may explain the purpose of the operators
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
XYZ(9&) ' Long values
XYZ(9L)
XYZ(9I) ' Int32 values
XYZ(9%)
XYZ(9S) 'Int16 value
XYZ("9"c) ' a single charcter
XYZ("9") ' a string
End Sub
Sub XYZ(ByVal arg As Object)
Debug.Print("arg type is " & arg.GetType.ToString)
'do some stuff depends on the type of arg
End Sub
.
Related
I try to run this code but iget the message implicit conversion from double to string vb.net i try different conversion but its the same
Private Sub TxtRemise_TextChanged(sender As Object, e As EventArgs) Handles TxtRemise.TextChanged
Dim TotalTTc As Decimal
TotalTTc = CDec(TotalHT.Text) + CDec(TXTMontantTva.Text)
TxtTTC.Clear()
TxtTTC.Text = TotalTTc) - val(TxtRemise.Text)
End Sub
You perform a mathematical operation, which will obviously result in a number, and you then assign that to the Text property of a TextBox, which is type String. If you want to assign to a String property then you need to assign a String. If you have a number, that means calling ToString on it.
I checked your code. There was some little mistakes. Check my example and comment if you had the solution to your question, thank you.
Public Class Form1
Private Sub TxtRemise_TextChanged(sender As Object, e As EventArgs) Handles TxtRemise.TextChanged
Dim TotalTTc As Decimal
TotalTTc = CDec(TotalHT.Text) + CDec(TXTMontantTva.Text)
TxtTTC.Clear()
TxtTTC.Text = (TotalTTc - CDec(TxtRemise.Text)).ToString
End Sub
End Class
Is there any way to get the parameters of a function dynamic?
Like:
Function(text As String, If text = "yes" text2 As String)
End Function
So the second one just gets asked, when the first is filled or a certain value?
Optional is no way, cause for example the third needs to be filled when the second one is already.
No, you can't do that. But you might accomplish something similar via Currying.
Currying takes a function that needs multiple arguments, and converts into a set of functions that each need a single argument, where prior functions in the set return the next function in the set.
Where this will still be problematic for your situation is .Net likes strongly-typed delegates. If the initial function needs to return a method with one argument for any case, it must do that for all cases.
However, that doesn't mean it returns the same function. You can still vary which function is returned based on the initial input argument.
So instead of this:
Function test(text As String, a As String) As String
If text = "yes" Then
Return text & a
Else
Return a & text
End If
End Function
test("yes", "foo") ' produces "yesfoo"
test("no", "foo") ' produces "foono"
We have this:
Function test(text As String) As Func(Of String, String)
If text = "Yes" Then
Return Function(a) text & a
Else
Return Function(a) a & text
End If
End Function
test("yes")("foo") ' produces "yesfoo"
test("no")("foo") ' produces "foono"
This won't do exactly what you want; it still requires the additional argument or not in every situation. But it might give you enough new flexibility to accomplish your ultimate goal. For example, perhaps you could combine this with a closure, where you never use the additional argument, but in the case where you need it the additional value is still available. Exactly how this will look or whether it's really possible or helpful will depend on the details of what you're trying to accomplish beyond the simple test code in the question.
You could handle what to pass in the button code.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim paramValue As String
If MyTestText = "yes" Then
paramValue = TextBox2.Text
Else
paramValue = TextBox1.Text
End If
End Sub
Private Function SomeFunction(text As String) As String
Dim ReturnValue As String = ""
'your code here
Return ReturnValue
End Function
Or you could pass both values and test in your Function code
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim ReturnedValue = SomeFunction(TextBox1.Text, TextBox2.Text)
End Sub
Private Function SomeFunction(text1 As String, text2 As String) As String
Dim ReturnValue As String = ""
If MyTestText = "yes" Then
'process text2
Else
'process text1
End If
Return ReturnValue
End Function
I am sure there are other ways to handle this.
Dim suffix As String = "_version"
I have a file called "Something_version1.jpg"
I need to split this so that I get "Something_version"
The following gets me "1.jpg"
filename = filename.Split(New String() {suffix}, StringSplitOptions.None)(1)
And the following gets me "Something"
filename = filename.Split(New String() {suffix}, StringSplitOptions.None)(0)
But what I need is "Something_version"
The suffix is dynamic, and can change.
Hope this is easier than I'm making it.
Thank you.
If you don't care about the "1.jpg" part at all, and all you want is the suffix and the part before the suffix, you can do what you have above (the second one) to get the prefix, and simply concatenate the prefix and suffix to get the answer you're looking for.
The split call might be overkill but it will do the job.
Try this!
Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim suffix As String = "_version"
Dim searchThis As String = "something_version1.png"
MsgBox(GetPrefix(suffix, searchThis))
End Sub
Function GetPrefix(suffix As String, searchThis As String) As String
Dim suffixLocation As Integer = searchThis.IndexOf(suffix) + suffix.Count
Return searchThis.Substring(0, suffixLocation)
End Function
End Class
What is the difference between doing this:
Public Sub MySub(ByVal MyString as String)
Dim TheString as String = MyString
myFunction(TheString)
'Some more code...
End Sub
Compared to this:
Public Sub MySub(ByVal MyString as String)
MyFunction(MyString)
'Some more code
End Sub
That is, is there a good reason to dimension a variable in a function/sub again before using it from the argument line? Or does it not matter?
Hope this makes sense, I wasn't sure how to word this question.
If it's a value based Type (e.g: string or integer, double etc.), unless it's passed using the reference (ByRef) instead of the value (ByVal), you shouldn't need to worry about storing it in another variable (unless you wish to have 2 copies)
If the function required a modified string, so you were changing it to fit that, the first code block would make some sense.
However--since it's equal, the only case I can think of you needing the first block of code is if you're needing to keep myString the same within that sub...but I would think if you were doing something like that, most of the time you would just have a totally different sub.
Because you used ByVal-- once you exit that sub, myString will once again be whatever it was initially set to before you entered the sub, because the mystring you're working with inside of the sub is just a copy of the value.
In contrast, if you used ByRef the changes made to the variable would be taken back to the main code and actually change the value of mystring.
You can read about the difference between ByVal and ByRef here: http://social.msdn.microsoft.com/Forums/vstudio/en-US/07b9d3b9-5658-49ed-9218-005564e8209e/what-is-the-difference-between-byval-and-byref
You can take all these concepts and play with how it works in a simple console program to further your understanding. That's what I did, here's some of the code I toyed with to double check what I was saying. Try changing where ByVal & ByRef is used, and maybe printing to the screen after you make a change to see what sticks and what doesn't.
Sub Main()
Dim someString As String = "This is some string."
MySub(someString)
Console.WriteLine(someString)
MyOtherSub(someString)
Console.WriteLine(someString)
Console.ReadLine()
End Sub
Public Sub MySub(ByVal myString As String)
Dim theString As String = myString
MyFunction(theString)
' First line printed in console.
Console.WriteLine(theString)
theString = "Hello."
Console.WriteLine(theString)
Console.WriteLine(myString)
myString = "I'm mystring."
Console.WriteLine(myString)
End Sub
Public Sub MyOtherSub(ByVal MyString As String)
MyFunction(MyString)
End Sub
Public Function MyFunction(ByRef mystring As String)
mystring += "myFunction is acting on this string."
End Function
I have 532.016, and I want to get only the 532 part in VB.NET. How can I do that?
Math.Truncate(myDecimal)
will strip away the fractional part, leaving only the integral part (while not altering the type; i. e. this will return the type of the argument as well, be it Double or Decimal).
Cast it to an Integer.
Dim myDec As Decimal
myDecimal = 532.016
Dim i As Integer = Cint(myDecimal)
'i now contains 532
You could use System.Text.RegularExpressions:
Imports System.Text.RegularExpressions 'You need this for "Split"'
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim yourNumber As String = 532.016 'You could write your integer as a string or convert it to a string'
Dim whatYouWant() As String 'Notice the "(" and ")", these are like an array'
whatYouWant = Split(yourNumber, ".") 'Split by decimal'
MsgBox(whatYouWant(0)) 'The number you wanted is before the first decimal, so you want array "(0)", if wanted the number after the decimal the you would write "(1)"'
End Sub
End Class
Decimal.floor(532.016) will also return 532.
Decimal.Floor rounds down to the closest integer.
However it won't work for negative numbers. See this Stack Overflow question for a complete explanation
Decimal.Truncate (or Math.Truncate) is really the best choice in your case.