Late binding an array - c#

I am seriously stumped as I can't find anything on late binding an array in VBA. Is this even possible? If yes, how? If not - why?
Note: I don't mind if it's possible using a native .Net/C# types like
Dim o as Object
set o = CreateObject("System.Array")
Even though the System.Array is COM visible it seems impossible to instantiate it.
Any idea how to late bind an array data type in VBA?
please, don't mention Dictionary or Collections as this question is quite specific to arrays
Additional info:
This is kind of a follow up on my other question. Since it seems impossible to pass a native VBA array to a native .Net collection without looping I was just wondering whether it's possible to late bind an array as both as seem safearrays which would mean they are compatible and therefore transfering a VBA array to a .Net one would be possible - please correct me if I am completely wrong.

set o = CreateObject("System.Array")
System.Array is an abstract class. So no, that can't possibly work. Array types are special, they are normally created by the compiler. The backdoor is Type.MakeArrayType() and you can construct that one.
Nothing you'd want to use. Don't try so hard, any VBA array is converted to System.Array already. It is just often a non-conformant array, one that doesn't have its first element at index 0. VBA likes 1, unless you use syntax like Dim arr(0 To 3) As Double or have Option Base 0 in effect. Not always possible, use Array.GetValue() to access a non-conformant array. Review your other question for a sample accessor wrapper.

Related

C# Array.IndexOf is static function, why? [duplicate]

I'm trying to understand the design decision behind this part of the language. I admit i'm very new to it all but this is something which caught me out initially and I was wondering if I'm missing an obvious reason. Consider the following code:
List<int> MyList = new List<int>() { 5, 4, 3, 2, 1 };
int[] MyArray = {5,4,3,2,1};
//Sort the list
MyList.Sort();
//This was an instance method
//Sort the Array
Array.Sort(MyArray);
//This was a static method
Why are they not both implemented in the same way - intuitively to me it would make more sense if they were both instance methods?
The question is interesting because it reveals details of the .NET type system. Like value types, string and delegate types, array types get special treatment in .NET. The most notable oddish behavior is that you never explicitly declare an array type. The compiler takes care of it for you with ample helpings of the jitter. System.Array is an abstract type, you'll get dedicated array types in the process of writing code. Either by explicitly creating a type[] or by using generic classes that have an array in their base implementation.
In a largish program, having hundreds of array types is not unusual. Which is okay, but there's overhead involved for each type. It is storage required for just the type, not the objects of it. The biggest chunk of it is the so-called 'method table'. In a nutshell, it is a list of pointers to each instance method of the type. Both the class loader and the jitter work together to fill this table. This is commonly known as the 'v-table' but isn't quite a match, the table contains pointers to methods that are both non-virtual and virtual.
You can see where this leads perhaps, the designers were worried about having lots of types with big method tables. So looked for ways to cut down on the overhead.
Array.Sort() was an obvious target.
The same issue is not relevant for generic types. A big nicety of generics, one of many, one method table can handle the method pointers for any type parameter of a reference type.
You are comparing two different types of 'object containers':
MyList is a generic collection of type List, a wrapper class, of type int, where the List<T> represents a strongly typed list of objects. The List class itself provides methods to search, sort, and manipulate its contained objects.
MyArray is a basic data structure of type Array. The Array does not provide the same rich set of methods as the List. Arrays can at the same time be single-dimensional, multidimensional or jagged, whilst Lists out of the box only are single-dimensional.
Take a look at this question, it provides a richer discussion about these data types: Array versus List<T>: When to use which?
Without asking someone who was involved in the design of the original platform it's hard to know. But, here's my guess.
In older languages, like C, arrays are dumb data structures - they have no code of their own. Instead, they're manipulated by outside methods. As you move into an Object oriented framework, the closest equivilent is a dumb object (with minimal methods) manipulated by static methods.
So, my guess is that the implementation of .NET Arrays is more a symptom of C style thinking in the early days of development than anything else.
This likely has to do with inheritance. The Array class cannot be manually derived from. But oddly, you can declare an array of anything at all and get an instance of System.Array that is strongly typed, even before generics allowed you to have strongly typed collections. Array seems to be one of those magic parts of the framework.
Also notice that none of the instance methods provided on an array massively modify the array. SetValue() seems to be the only one that changes anything. The Array class itself provides many static methods that can change the content of the array, like Reverse() and Sort(). Not sure if that's significant - maybe someone here can give some background as to why that's the case.
In contrast, List<T> (which wasn't around in the 1.0 framework days) and classes like ArrayList (which was around back then) are just run-of-the mill classes with no special meaning within the framework. They provide a common .Sort() instance method so that when you inherited from these classes, you'd get that functionality or could override it.
However, these kinds of sort methods have gone out of vogue anyway as extension methods like Linq's .OrderBy() style sorting have become the next evolution. You can query and sort arrays and Lists and any other enumerable object with the same mechanism now, which is really, really nice.
-- EDIT --
The other, more cynical answer may just be - that's how Java did it so Microsoft did it the same way in the 1.0 version of the framework since at that time they were busy playing catch-up.
One reason might be because Array.Sort was designed in .NET 1.0, which had no generics.
I'm not sure, but I'm thinking maybe just so that arrays are as close to Primitives as they can be.

Possible to derive from an array?

Currently I have an class that contains an array and an integer.
I have millions of these objects, and would like to save memory by just having an array so I save 12 bytes for each object (by not having to allocate a class wrapper for each one). This will save a lot of memory.
Unfortunately, I need to store the integer as well. I was thinking about just storing it in the first index, but it is slightly messy. I was hoping I could just derive from an array and insert the int member in the subclass, but apparently that is disallowed by the compiler.
Are there any alternatives? I suppose I could just copy and paste the array class from the referencesource framework and add my property, but it seems like overkill.
You can't derive from an array (and "copy and paste the array class from the reference source framework" will likely not do you much good as arrays are very integrated into language/framework).
One option may be to use struct with integer and array - you'll get major pain to deal with struct, but if careful it will provide you exactly what you looking for (if your "integer value" is mutable or the array needs to change size - I'd strongly recommend forgetting you've seen such suggestion).

Lazarus pointer type in C#

I am trying to convert a lazarus project to c#. It's been good so far but i have a problem now.
There is a code like this:
xActor = record
Id: integer;
Value: integer;
Name: ansistring;
Height: integer;
Gender : Boolean;
Position : byte;
end;
I created this in c# as a struct. However, after this code i saw something like this
PxActor = ^xActor;
I've researched a bit and found out that this means create a type that includes xActor's pointers i may be wrong tho.
Then i saw a more interesting record in the code
yActor = packed record
Actor: array [1..9] of PxActor;
end;
at this point i have no idea how to convert these to c# since i have no idea what PxActor = ^xActor; means.
Thanks in advance
C# has two different kinds of an object - a reference-type, and a value-type.
The code you have is mixing the two (very common in C/Pascal), because you have a C# value-type (the struct xActor) and a reference-type referring to the same type (the pointer PxActor), which isn't quite possible in C#.
However, there are ways to emulate similar behaviour. But first, you have to think about the logical way this is supposed to work. Maybe this is just a performance tweak (e.g. the array of PxActor is used instead of xActor because you want to save up on the extra memory from having the whole xActor structure there). Perhaps it's rather that you want to have the same value available from multiple places, and mutable.
Both cases can usually be solved by simply making xActor a class - in C#, that means that it will always be a reference type (not something that makes sense in C/Pascal, but the predominant object in C# and similar languages). However, you need to manually check every place where anything of type xActor or PxActor is used, and make sure the value/reference semantics are still the same. This can lead to some hard to find bugs, depending on the original code.
Another option is to create a wrapper class. So you'll keep your struct xActor, but you'll also create a class PxActor, which will have a single xActor field. This is not an exact analogue of Pascal's pointers, but if you're careful, it can be used in a similar way. The main difference is that you can't capture a pointer to an existing value somewhere - you can only create a new PxActor, with it's own copy of xActor. Anyone accessing the PxActor instance will also be working with the same xActor instance, but anytime you store the xActor itself, it's a new copy. But in the simplest case, you can replace manual allocations of xActor and a subsequent # into new PxActor(), and any variable^.Gender access to variable.ActorField.Gender.
Just during the refactoring itself, it would also be possible to use C#'s pointers. They are a bit limited compared to C/Pascal's, but they might work for your cases. Except for that string value. However, pointers have lots of costs, so you don't want to use them unless they are a good idea, and this isn't that case :)
In other words, it's usually a bad idea to do a 1:1 translation from Pascal to C#. You need to figure out what the semantics behind all the stuff is. Finding all the usages of a given type is going to be a huge chore. Translating line-by-line can easily paint you into a corner. C# is a very safe language, and CLR is very good at making sure everyone can talk with each other, but this also means a few differences in stuff like value/reference passing and similar. Now, IIRC, Pascal has value semantics by default, so using struct and similar should mostly work well in C# as well. You'll have to analyze any use of pointers, though. Sometimes, you can use C#'s out or ref instead of a pointer - go for that. But the case you have here isn't quite like that - it's a pointer stored in another type, not just passed as an argument. However, that still doesn't tell us much about how this is supposed to work in practice - maybe it's just a way to work around Pascal's limitations; maybe you'd use List<xActor> in C# instead of array of PxActor.
Of course, that's usually the best option. Where possible, use idiomatic C#, instead of just trying to code Pascal in C#. While there are many similarities, there's also a large amount of differences that can bite you, and make your work much harder than necessary. Find the places where List<SomeType> is going to work better than array of PSomeType. Find the places where ref and out can be used instead of PSomeType. Find where struct makes sense, and where class would be better. This applies to many subtle differences that can ruin your day, so you'll probably be finding many issues over time, but it's a journey :)

Range[] instead of get_Range()

http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.worksheet.get_range.aspx it says to use the Range property instead of get_Range(Object Cell1, Object Cell2).
They are both doing the same thing, Gets a Microsoft.Office.Interop.Excel.Range object that represents a cell or a range of cells. So, what's the difference except that this is a method and another is a property? Why are they pointing on use of Range[], what's the reason for it?
Range() is faster than Range[]
By practice we have noticed it the case. But here should define a reason to say so.
This shortcut is convenient when you want to refer to an absolute range. However, it is not as flexible as the Rangeproperty as it cannot handle variable input as strings or object references. So at the end of the day you will still end up referring the long way. Although the shorty provides readability. Hence might as well get it right the first round without more resources spending.
Now why is it slow? In the compiling.
"During run-time Excel always uses conventional notation (or so I've been told), so when the code is being compiled all references in shortcut notation must be converted to conventional range form (or so I've been told). {ie [A150] must be converted to Range("A150") form}. Whatever the truth of what I've been told, Visual Basic has to memorize both its compiled version of the code and whatever notation you used to write your code (i.e. whatever's in the code module), the workbook properties for the file size (the memory used) thus goes up slightly. "
As you see my answer was more in line with VBA. However after some research it is sort of proved that VBA side doesn't do much slowing down. So you only need to take care of the C# side. #Hans gives you a better answer in C# perspective. Hope combining both that you will get a great performing code :)
Here is some finding on the performance of Range[] vs Range() in Excel
If you use C# version 4 and up then you can use the Range indexer. But you have to use get_Range() on earlier versions.
Do note that there's something special about it, the default property of a COM interface maps to the indexer. But the Range property is not the default property of a Worksheet, it is just a regular property. Trouble is, C# does not permit declaring indexed properties other than the indexer. Works in VB.NET, not in C#, you had to call the property getter method directly. By popular demand, the C# team dropped this restriction in version 4 (VS2010). But only on COM interfaces, you still cannot declare indexed properties in your own code.
I have used both and both returned the same results. I think Range[] actually uses get_Range() internally.
For a question of naming convention I only use Range[] now.

Using COM object from C++ that in C#.NET returns object []

I have a COM object that I'm trying to use from C++ (not .NET), and all of the example programs and manual are written assuming the use of C#.NET or VB.NET. COM is new to me so I'm a bit overwhelmed. I'm using #import on the TLB but am struggling to deal with the variants that are used as parameters. I have one particular method, that according to the docs and the example programs in C#.NET, is supposed to return an object[]. Then I'm supposed to cast the first entry in this array to a ControlEvent which then tells me what to do with the rest of the objects in the array. The C#.NET example looks like:
object [] objEvent = (object []) Ctl.GetEvent();
ControlEvent ev = (ControlEvent) objEvent[0];
In my case, GetEvent is returning me a _variant_t and I need to know how to convert this to an object[] so that I can further process. Its not clear to me even how I express 'object' in C++. I see _variant_t documentation showing me a million things I can convert the variant to, but none of them seem to be converting to anything I can use. I'm hoping for some assistance converting the above C#.NET code to Visual C++
Thanks.
Typically, you look at the vt member of the variant to see what type of thing it actually is. In this case I would expect it to be an array, so you would expect that the vartype would be some variation on VT_ARRAY (usually it is bitwise OR'ed with the type of the members). Then, you get the parray member which contains the SAFEARRAY instance that actually holds the array, and use the normal safe array functions to get the data out of the array.
I haven't done this, but from reading the documentation for the _variant_t class (and the comments below which corrected my original post), I think you should read the vt field of the _variant_t instance (actually the VARTYPE vt field of the VARIANT instance: the _variant_t instance directly derives from VARIANT) to see what type of thing it contains, as described in the reference documentation for the VARIANT struct. One you know what type of thing is contained in the variant, use the corresponding type-specific operator to read it.
You'll be in for some hurt if you try to use COM without understanding it (and you may want a book which describes that); you may well need to know about the IUnknown interface and the AddRef method, for example.

Categories

Resources