Check the TypeArgument of the ForEach activity. If you’re passing a String (string array), it should be String. By default it’s Object, that’s why you need .ToString call.
For other methods @umesh_desh explanation is ok, although there’s a little error, as they’re not String method calls, they’re Object method calls. For GetHashCode and GetType it doesn’t make much difference, but for equality comparison it is important to note that:
The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object. Bitwise equality means the objects that are compared have the same binary representation.
There are some subtleties to this. For example:
Let’s take 2 DataRow objects (reference type) from the same DataTable that has 2 columns - FirstName (string), Age (Int32).
If both of them have values of
FirstName = "John", Age = 30 you’d think that
row1 = row2 would return True, but it will give False, because they’re not the same object (that’s reference equality).
But if you compare each of their fields individually, f.e. (
row1.Field(Of String)(0) == row2.Field(Of String)(0) AndAlso row1.Field(Of Integer)(1) == row2.Field(Of Integer)(1)) it should return True. This is because the values of those are equal.
For Strings it’s especially important to make sure you’re treating them as String when comparing, because they’re rather “special” in .Net land - they’re a reference type that behaves like a value type. So if the compiler doesn’t know it’s a String it will treat it as Object and use reference equality (which for Strings, due to the way they work, is always false), while you want to compare their values.
So for the same 2 DataRow’s from above if you’d use just
row1(0) = row2(0) (without using the
Field(Of Type) call or using .ToString) you’d also get False which can be sometimes hard to debug.
See also here for some examples (fair warning - a “little” technical):