Understanding assignment/comparison vb.net - vb.net

This is my first time on Stack Overflow and I am trying to understand what '=' means in the last line of this code:
Dim label As Label = Me.labels.Item(String.Concat(New Object() { movimiento.Sector1.ID, "-", movimiento.X1, "-", movimiento.Y1 }))
Dim dictionary As Dictionary(Of Label, Integer)
Dim label3 As Label
dictionary = Me.demandas2.Item(label3 = label) = (dictionary.Item(label3) - 1)
Any kind of help will be welcome, thanks in advance!

The equals sign (=) is used for two entirely different operators in VB.NET. It is used as the assignment operator as well as for the equality test operator. The operator, to which the character evaluates, depends on the context. So, for instance, in this example:
Dim x As Integer = 1
Dim y As Integer = 2
Dim z As Integer = x = y
You might think, as in other languages, such as C#, that after executing that code, x, y, and z would all equal 2. However, VB treats the second equals sign as an equality test operator. Therefore, in actuality, it's doing this:
If x = y Then
z = True
Else
z = False
End If
You'll notice, though, that we are then trying to assign a boolean value to an integer variable. If you have Option Strict On (as you should), it would not allow you to do that. If that's really what you wanted to do, it would force you to cast it to an integer, which makes it slightly more obvious:
z = CInt(x = y)
However, it's still confusing, so typically, this kind of thing is discouraged in VB.NET. So, I suspect that the code you posted wouldn't even compile if Option Strict was turned on. But, this is what it's actually trying to do:
Dim temp1 As Boolean = (label3 = label) ' Evaluates to False
Dim temp2 As Boolean = (Me.demandas2.Item(temp1) = (dictionary.Item(label3) - 1)) ' Likely evaluates to False
dictionary = temp2 ' Couldn't possibly be a valid assignment

Let's look at this line of code:
dictionary = Me.demandas2.Item(label3 = label) = (dictionary.Item(label3) - 1)
The first = is an assignment. So we assign the right part to the dictionary. Now for the right part:
Me.demandas2.Item(label3 = label) = (dictionary.Item(label3) - 1)
The = between the two expressions is a comparison, so it returns a Boolean. So the supposed "dictionary" is assigned a boolean value. If we check the left part of that expression:
Me.demandas2.Item(label3 = label)
Once again, the = sign here is doing a comparison, so if label3 is the same as label, then the code would be equivalent to Me.semandas2.Item(True). This seems strange.
Overall, this code doesn't make much sense, and I'd be surprised if it compiled, considering it tries to assign a boolean to a dictionary. It certainly wouldn't compile with Option Strict On.

Thanks a lot, everyone. The snippet was result of decompile a dll. I was trying to help a partner.
.Net reflector decompiled based on VB.Net code, that was a mistake.
Finally we see that first it should decompile using C# code, that gives a complete different meaning to the code:
if (movimiento.Contenedor.Demanda2)
{
Dictionary<Label, int> dictionary;
Label label3;
(dictionary = this.demandas2)[label3 = label] = dictionary[label3] - 1;
if (this.demandas2[label] == 0)
{
label.ForeColor = Color.Black;
}
(dictionary = this.demandas2)[label3 = label2] = dictionary[label3] + 1;
label2.ForeColor = Color.DarkOrange;
}

Related

Number Expected, Got Boolean

When I run this code, I get an error message that looks like this:
Runtime Error:
AI.lua:7: bad argument #2 to 'getlocal' (number
expected, got boolean)
What can I do to resolve this? I need the Boolean value.
Anything = not nil
Nothing = not Anything
Everything = Anything and not Nothing
Overtaking = Anything and Nothing
God = Everything and Overtaking
Divinity = God and not not God
Better = debug.getlocal(1, Divinity)
x = ""
repeat
i = 32
repeat
i = i + 1
a = string.char(i)
if Better == true then
x = x .. a
else x = x
end
until (i == 126)
until (x == x .. "")
print (x)
First of all, getlocal requires an integer as the second argument and you passing boolean, so it won't work for you. Second, getlocal returns the local variables declared in a certain scope, so that really depends on what your'e trying to do here. I cannot see any locals in your code, so using getlocal won't get you anywhere.
Take a look at getlocal usage.

understanding VB code

i m working on translating code from VB to C#, though there are lots of great conversion websites, i still find the code ambiguous to me, since the documentation is really poor it approaches to useless, i thought about posting it here to see if i can get it clearer.
i need some elaboration on the code given below, and whats the use of the Buffer[] in the method below:
Function hexToBin(ByVal str As String, ByRef Buffer() As Byte)
Dim strRemain As String
Dim firstChar As Boolean
Dim i, count, inputLen, remainLen As Integer
i = 0
count = 0
firstChar = True
strRemain = str
While Len(strRemain) > 0
If Mid(strRemain, 1, 1) = " " Then
firstChar = True
strRemain = Mid(strRemain, 2)
ElseIf firstChar = True Then
If Len(strRemain) = 1 Then
Buffer(count) = myVal(strRemain)
ElseIf Len(strRemain) >= 2 Then
Buffer(count) = myVal(Mid(strRemain, 1, 1)) * 16 + myVal(Mid(strRemain, 2, 1))
strRemain = Mid(strRemain, 3)
End If
count = count + 1
firstChar = False
Else
strRemain = Mid(strRemain, 2)
End If
Wend
hexToBin = count
End Function
see, i know this code converts from hex to binary as the name suggests, yet i cant really figure the use of the Buffer[] in the context, i looked up the Mid function in string VB, but still can't figure out the use of the Buffer[] in this function, i would appreciate if someone explained the use of the buffer.
In the code above, the parentheses are used to access elements of an array. So, Buffer(i) refers to the ith element of the array Buffer.
You can learn more about arrays in VB from any text book, or indeed from MSDN: http://msdn.microsoft.com/en-us/library/wak0wfyt.aspx
As for why the array Buffer is used in the first place, well that's to store the output of the function. The function takes a hex string as input and populates the byte array Buffer with the binary equivalent.
This does seem to be rather inefficient code though. And it presents a somewhat clumsy interface because it asks the caller to allocate the array. Rather than translating it, I think I would start here: How can I convert a hex string to a byte array?

Find a variable with concatenation

I would like to find a variable with concatenation.
Exemple :
Dim oExcelRangeArray1(0, 0) As Object
Dim oExcelRangeArray2(0, 0) As Object
Dim oExcelRangeArray3(0, 0) As Object
For i As Integer = 1 To 3
oExcelRangeArray & i = xl.Range("A1:Z400").Value
Next
but oExcelRangeArray & i doesn't work.
Thank you
For the extent of my knowledge, there is no way to achieve what you are trying to do directly, because oExcelRangeArray & i will not be evaluated as a separate step before the variable assignment happens.
In my mind you have two choices:
Assign each variable individually,
oExcelRangeArray1 = x1.Range("A1:Z400").Value
oExcelRangeArray2 = x1.Range("A1:Z400").Value
oExcelRangeArray3 = x1.Range("A1:Z400").Value
oExcelRangeArray4 = x1.Range("A1:Z400").Value
Or, add each array to a list, and iterate through it,
Dim oExcelRangeArrayList As New List(Of Object)
oExcelRangeArrayList.Add(oExcelRangeArray1)
oExcelRangeArrayList.Add(oExcelRangeArray2)
oExcelRangeArrayList.Add(oExcelRangeArray3)
oExcelRangeArrayList.Add(oExcelRangeArray4)
For i As Integer = 0 To 3
oExcelRangeArrayList(i) = x1.Range("A1:Z400").Value
Next
[Note: Writing this freehand without checking it, code may not be verbatim; hopefully you get the concept. Corrections welcome.]

Dynamic query Linq to xml VB.NET

Hey,
I want to write a query that the "where" in the query is a string something like"
Dim query as string= "Name =xxxx and Date > 10 "
Dim t = from book in doc.Descendants("books") Select _
[Name] = book..value, [Date] = book..value....
Where (query)
I build the query string on run time
Thanks...
I'm not saying this is your case but I see this a lot from people that came from ASP classic where we used to build dynamic SQL strings all of the time. We tend to hope that LINQ will give us some more power in part of the code but let us use strings elsewhere. Unfortunately this isn't true. Where takes a boolean argument and there's no way around that. You can write your own parser that uses reflection and eventually returns a boolean but you'd be writing a lot of code that could be error prone. Here's how you really should do it:
Assuming this is our data class:
Public Class TestObject
Public Property Name As String
Public Property Job As String
End Class
And here's our test data:
Dim Objects As New List(Of TestObject)
Objects.Add(New TestObject() With {.Name = "A", .Job = "Baker"})
Objects.Add(New TestObject() With {.Name = "B", .Job = "President"})
Objects.Add(New TestObject() With {.Name = "C", .Job = "Bus Driver"})
Objects.Add(New TestObject() With {.Name = "D", .Job = "Trainer"})
What you want to do is create a variable that represents the data to search for:
''//This variable simulates our choice. Normally we would be parsing the querystring, form data, XML values, etc
Dim RandNum = New Random().Next(0, 3)
Dim LookForName As String = Nothing
Select Case RandNum
Case 0 : LookForName = "A"
Case 1 : LookForName = "B"
Case 2 : LookForName = "C"
End Select
''//Query based on our name
Dim Subset = (From O In Objects Select O Where (O.Name = LookForName)).ToList()
If sometimes you need to search on Job and sometimes and sometimes you don't you just might have to write a couple of queries:
Dim Subset As List(Of TestObject)
Select Case RandNum
Case 0
Subset = (From O In Objects Select O Where (O.Name = "A" And O.Job = "Baker")).ToList()
Case Else
Select Case RandNum
Case 1 : LookForName = "B"
Case 2 : LookForName = "C"
End Select
Subset = (From O In Objects Select O Where (O.Name = LookForName)).ToList()
End Select
And just to explain writing your own query parser (which is a path that I recommend you DO NOT go down), here is a very, very, very rough start. It only supports = and only strings and can break at multiple points.
Public Shared Function QueryParser(ByVal obj As Object, ByVal ParamArray queries() As String) As Boolean
''//Sanity check
If obj Is Nothing Then Throw New ArgumentNullException("obj")
If (queries Is Nothing) OrElse (queries.Count = 0) Then Throw New ArgumentNullException("queries")
''//Array of property/value
Dim NameValue() As String
''//Loop through each query
For Each Q In queries
''//Remove whitespace around equals sign
Q = System.Text.RegularExpressions.Regex.Replace(Q, "\s+=\s+", "=")
''//Break the query into two parts.
''//NOTE: this only supports the equal sign right now
NameValue = Q.Split("="c)
''//NOTE: if either part of the query also contains an equal sign then this exception will be thrown
If NameValue.Length <> 2 Then Throw New ArgumentException("Queries must be in the format X=Y")
''//Grab the property by name
Dim P = obj.GetType().GetProperty(NameValue(0))
''//Make sure it exists
If P Is Nothing Then Throw New ApplicationException(String.Format("Cannot find property {0}", NameValue(0)))
''//We only support strings right now
If Not P.PropertyType Is GetType(String) Then Throw New ApplicationException("Only string property types are support")
''//Get the value of the property for the supplied object
Dim V = P.GetValue(obj, Nothing)
''//Assumming null never equals null return false for a null value
If V Is Nothing Then Return False
''//Compare the two strings, return false if something doesn't match.
''//You could use String.Compare here, too, but this will use the current Option Compare rules
If V.ToString() <> NameValue(1) Then Return False
Next
''//The above didn't fail so return true
Return True
End Function
This code would allow you to write:
Dim Subset = (From O In Objects Select O Where (QueryParser(O, "Name = A", "Job = Baker"))).ToList()
No, there is nothing directly like what you're looking for where you can pass in a string. As they say, when all you have is a hammer, everything looks like a nail...The real problem is that you need to learn what LINQ is good at and apply it to your code (if it is a good fit), rather than try and make it do what you could with a dynamically built SQL query string.
What you should probably be doing is making those "Where" clauses strongly typed anyway. Your current code has a lot of potential to blow up and be hard to debug.
What you could do instead is something like this (sorry, using C#, been a while since I've touched VB.NET):
var query = from book in doc.Descendants("books")
select book;
if(needsNameComparison)
{
query = query.where(book.Name == nameToCompare);
}
if(needsDateComparison)
{
query = query.Where(book.Date > 10);
}
List<book> bookList = query.ToList();
With LINQ, "query" isn't actually run until the "ToList()" call. Since it uses late execution, the query is dynamic in that it's being built on until it actually needs to run. This is similar to the code you were looking to use before since you were building a query string ahead of time, then executing it at a specific point.

VB.NET overloading array access?

Is it possible to overload the array/dict access operators in VB.net? For example, you can state something like:
Dim mydict As New Hashtable()
mydict.add("Cool guy", "Overloading is dangerous!")
mydict("Cool guy") = "Overloading is cool!"
And that works just fine. But what I would like to do is be able to say:
mydict("Cool guy") = "3"
and then have 3 automagically converted to the Integer 3.
I mean, sure I can have a private member mydict.coolguy and have setCoolguy() and getCoolguy() methods, but I would prefer to be able to write it the former way if at all possible.
Thanks
To clarify - I want to be able to "do stuff" with the value. So for instance, say I have
myclass.fizzlesticks ' String type
myclass.thingone ' Numerical type, say integer
and then I want to be able to write
myclass("thingummy") = "This is crazy"
which fires off a method that looks like this
Private sub insanitea(Byval somarg as Object, Byval rhs as Object)
If somearg = "thingummy" And rhs = "This is crazy" Then
thingone = 4
fizzlesticks = rhs & " and cool too!"
End If
End Sub
This isn't the precise use-case, but I think it does a better job of being able to illustrate what I'm looking for?
No, you can't overload the array access operators in Visual Basic.
Currently the only operators you can overload are:
Unary operators:
+ - Not IsTrue IsFalse CType
Binary operators:
+ - * / \ & Like Mod And Or Xor
^ << >> = <> > < >= <=
Why can't you do the following:
mydict("Cool guy") = 3 //without quotes
Then you can do
dim x = mydict("Cool guy") + 7
//x returns 10
Or, you could do a Int32.tryParse
dim x as integer
if int32.tryParse(mydict("Cool guy"), x) then
return x + 7 //would return 10
end if