C# to VB.NET array initialization - c#

In C#, I can declare an array variable like this
object[] Parameters;
and initialize it like this:
Parameters = new object[20];
In Visual Basic, declaring and initializing an array is easy:
Dim Parameters(19) As Object
Dim Parameters As Object(19) ' Alternative syntax
How would I initialize an array variable that has already been declared in VB.NET?
Parameters = New Object(19) doesn't work.
For example, how would I translate the following to VB.NET?
int value = 20;
object[] Parameters;
if (value > 10)
{
Parameters = new Object[20];
}

Basically the same Visual Basic code as the others, but I'd use the opportunity to add a bit of style:
Dim value = 20 ' Type inference, like "var" in C#
Dim parameters() As Object ' Could also be "parameters As Object()"
If value > 10 Then
parameters = New Object(19) {} ' That's right, Visual Basic uses the maximum index
End If ' instead of the number of elements.
Local variables (parameters) should start with a lowercase letter. It's an established convention and it helps to get correct syntax highlighting in Stack Overflow (this also applies to the original C# code).
So, why are the braces {} required in Visual Basic? In Visual Basic, both method calls and array access use parenthesis (...). Thus, New X(4) could mean:
Create a new object of type X and pass 4 to the constructor,
Create a 5-element [sic] array of X.
To distinguish the two cases, you use the array initializer syntax in the second case. Usually, the braces contain actual values:
myArray = New Integer() {1, 2, 3}

Dim value As Integer = 20
Dim Parameters() as object
If value > 10 then
Parameters = new Object(value - 1){}
end if

If you are lazy like me you could use an online converter which yields:
Dim value As Integer = 20
Dim Parameters As Object()
If value > 10 Then
Parameters = New [Object](19) {}
End If
And if you are not like me and want to learn VB.NET head over to the documentation of the VB.NET syntax and start reading.

Related

How can I represent Dim order(4) As Int16 in C#?

How can I use Dim order(4) As Int16 which I have declared in public class of VB in C# format?
where,
order(0)=0;
order(1)=0;
order(2)=0;
order(3)=0;
That are default values, just initialize the array with the right size and you are finished.
Note that you want a length of 4 but
Dim order(4) As Int16
Initializes an array with the length 5. So you want this in VB.NET:
Dim order(3) As Int16
and this in C# (note that it's 4 here for the length 4):
short[] order = new short[4];
which is an alias for:
System.Int16[] order = new System.Int16[4];
It's an array, in c# it looks like this (with initializer):
var i = new short[] {0,0,0,0};
That looks like simply:
short[] order = new short[4];
You could also explicitly specify the defaults, but 0 is implicit anyway and it is cheaper not to do this, but:
short[] order = new short[] {0, 0, 0, 0};
Note that short is an alias for System.Int16. If this is a local variable (as opposed to a field), you can also simplify it further using var:
var order = new short[4];

How to retrieve Variant array from VBA in C#?

I call a function in VBA, from which I want to retrieve an array of strings. For that I declared a function with ByRef parameter of type Variant:
Public Function TestErrorsInArray(ByVal path As String, ByRef errors As Variant) As String
errors = Array("string1", "string2", "string3")
End Function
I tested it in VBA with following sub:
Public Sub TestTestErrorsInArray()
Dim arr As Variant
arr = Array("foo", "bar")
TestErrorsInArray "", arr
End Sub
And it works OK - arr values are changed to those from errors list.
In C# I call it like this:
object errors = null;
var test = WordTools.GetWordApplication().Run("TestErrorsInArray", "", errors);
Unfortunatelly, it seems that errors variable doesn't change at all... It stays as null. If I initiate it as empty array, it stays as empty array etc.
Any ideas what am I doing wrong?

VB.NET equivalent of C# object initializer of an anonymous type

I'm not experienced with advanced features of .NET type system. I cannot find out of what type is zz (what can be written instead of var. Or is var the best choice here?)
string foo = "Bar";
int cool = 2;
var zz = new { foo, cool }; // Watches show this is Anonymous Type
but most importantly, how the equivalent can be achieved in VB.NET code (this is what I actually need).
Dim Foo As String = "Bar"
Dim Cool As Integer = 2
Dim zz = {Foo, Cool} 'This is not an equivalent of above, I'm getting an array
I have searched several C# sources, used code watches and learned about how zz looks internally but I'm unable to make next step.
(The purpose of my effort is something like this in VB.NET.)
Your code would not even compile with OPTION STRICT set to ON which is highly recommended. No type can be derived from String + Int32. It would compile if you want an Object():
Dim zz As Object() = {Foo, Cool}
But you want to create an anonymous type, use New With:
Dim zz = New With {Foo, Cool}
http://msdn.microsoft.com/en-us/library/bb385125.aspx
With .NET 4.7 and Visual Basic 2017 you can also use ValueTuples with names:
Dim zz = (FooName:=foo, CoolName:=cool)
Now you can access the tuple items by name:
int cool = zz.CoolName;
https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/tuples

Declaring collections in C#

My question is: What is the most efficient and correct, for large set of data ?
_pointBuffer1 = new Point3DCollection {
new Point3D(140.961, 142.064, 109.300), new Point3D(142.728, 255.678, (...)
-- or --
_pointBuffer1.Add(new Point3D(140.961, 142.064, 109.300)); _poitBuffer1.Add(142.728, (...)
Or is it the same ?
Point3D is declared as a Point3DCollection, but my question is for any object collection (could be Int32 for example) ..
I would strongly suggest using the collection initializer for the sake of clarity (although I'd use some newlines as well).
They don't quite end up as the same IL, mind you. The first ends up being equivalent to:
var tmp = new Point3DCollection();
tmp.Add(new Point3D(140.961, 142.064, 109.300));
tmp.Add(new Point3D(142.728, 255.678));
...
_pointBuffer1 = tmp;
In other words, the assignment to the eventual variable is only made after all the Add calls.
This is important if your Point3D constructor somehow references _pointBuffer1!
Both are compiled to the same IL. Collection initializers are just syntactic sugar. They will call the Add method. Example:
var res = new List<int>() { 1, 2, 3 };
is compiled to:
List<int> <>g__initLocal0 = new List<int>();
<>g__initLocal0.Add(1);
<>g__initLocal0.Add(2);
<>g__initLocal0.Add(3);
List<int> res = <>g__initLocal0;
The only difference is an additional local variable being declared.
Collection initialisation is syntactic sugar. By this I mean that it is a convenient shorthand that is understood by the complier. The compiler will produce code that is logically identical to calling the collection's add method for each element.

Need help converting C# to vb. "array initializer is missing 1 elements"

I am trying to convet the following code from C# to Vb using 3.5 framework.
Here is the code in C# that I am having trouble with.
MethodInfo mi = typeof(Page).GetMethod("LoadControl", new Type[2] { typeof(Type), typeof(object[]) });
I thought it would be like this in VB;
Dim mi As MethodInfo = GetType(Page).GetMethod("LoadControl", New Type(2) {GetType(Type), GetType(Object())})
but I am getting the following error "array initializer is missing 1 elements"
The other line that I am having trouble with and getting the same error is
control = (Control) mi.Invoke(this.Page, new object[2] { ucType, null });
I tried this in vb but it does not work.
control = DirectCast(mi.Invoke(Me.Page, New Object(2) {ucType, Nothing}), Control)
ucType is defined as follows
Dim ucType As Type = Type.[GetType](typeName(1), True, True)
Any help would be greatly appreciated.
VB.Net arrays are 0-based, but declared using the highest-index rather than the number of items. So a 10-item array, indexed 0..9, is declared as Item(9).
With that said, the real solution to your problem is to let the compiler figure out the array length, like so:
Dim mi As MethodInfo = GetType(Page).GetMethod("LoadControl", New Type() {GetType(Type), GetType(Object())})
In VB.NET the array declaration takes the upper bound of the array, not the length like C# does (kind of silly if you ask me). Because of this, you need to reduce the number passed into your array declarations by 1 (since arrays are zero-based).
For the first line you need to change new Type(2) into New Type(1).
Dim mi As MethodInfo = GetType(Page).GetMethod("LoadControl", New Type(1) {GetType(Type), GetType(Object())})
In VB.Net the number specified in the array initializer is the highest accessible index vs. the length. The second line you mentioned has the same problem and solution.
VB uses the upper bound as the argument for arrays.
new byte[X]
new byte(X) 'wrong, 1 more element
new byte(X-1) 'correct, kinda confusing
new byte(0 to X-1) 'correct, less confusing
I suggest using the (0 to X-1) style, because it's a lot clearer. It was a lot more important in the vb6 days when array(X) could mean 0 to X or 1 to X depending on the context.
It will be like this -
Dim mi As MethodInfo = GetType(Page).GetMethod("LoadControl", New Type(1) {GetType(Type), GetType(Object())})
The other one will be -
control = DirectCast(mi.Invoke(Me.Page, New Object(1) {ucType, Nothing}), Control)
There is an online version available at http://converter.telerik.com which converts
C# to VB and vice versa.

Categories

Resources