Range[] instead of get_Range() - c#

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.

Related

What does Resharper have against the commonly-used getRange() in Excel Interop?

Almost all of the example code online for C# Excel interop has stuff like this:
monthlyChartRange = _xlSheetChart.get_Range("A3", "C4");
Yet, Resharper turns up its nose at it and demands: "Use indexed property" If you accede to its wishes (and I love R#, so I always say, "As you wish"), it changes it to:
monthlyChartRange = _xlSheetChart.Range["A3", "B4"];
Why? How is Range better than get_Range? How is the former any more indexed than the latter?
Resharper is trained to use properties instead of the underlying Getter because it's easier code to read and more OO-like. The property just calls the getter under the covers.
The COM port of Excel automation just exposed the Getter, even though this is not really all that OO-ish.
BTW, I recommend using Aspose Cells instead of Office automation. It's like ten trillion times faster.
Yet, Resharper turns up its nose at it and demands: "Use indexed property"
A bit of an intro - COM goes way back. You must bare in mind that COM is a binary protocol and that some COM-aware languages have no concept of properties.
COM indexed properties are generally defined like so:
[propget, id(DISPID_VALUE), helpstring("blah")]
HRESULT Item([in] long Index, [out, retval] BSTR* Item);
The dispatch ID is DISPID_VALUE which informs clients that this is the default property typically used for indexed properties. Notice how it is defined as a property get but interestingly it takes a parameter index. The notion of a property getter that takes an argument can be confusing to some programming languages as we shall see.
Fully COM-compliant Client Languages
A good COM-aware client language (such as VB6; VBA; .NET) will allow you to interact with the object like so:
string thing = myObject.Item[2];
These languages sees that this particular property is a propget however it takes and in parameter. The fact that it is marked as DISPID_VALUE is rather riveting because that tells COM clients that it is the default property. Putting two and two together, clients will realise that it must be a dandy indexed property so that they can use groovy square brackets.
It's important to realise that this is just sugar syntax. It's just a more convenient way to call the default indexed property. Behind the scenes, it will call the same COM property getter method as per un-compliant languages as shown below.
Not-so-COM-compliant Client Languages
Some programming languages (like Visual Objects 2.6), freak out (then again I freak out when I use VO) when they see a COM property that takes a parameter and so it falls back to the underlying method declaration where it essentially treats it as a method call that takes an index parameter and returns a string:
string thing = myObject.get_Item(2) // Boo!
These clients probably also missed the important fact that the property was marked as DISPID_VALUE.
Now with c#, you are arguably free to use the method-style operations to query a property or do as COM was designed and use index property notation.
After all, c# is OO; understands properties; understands indexers so why wouldn't you use them?
Hence why Resharper is prompting you to use the COM-preferred indexed style. It's no different to how you would use a regular c# class.

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 :)

Late binding an array

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.

What does "o" mean as a variable prefix?

in oCn? What is the rule?
using(SqlConnection oCn = new SqlConnection(
"Server=(local);Database=Pubs;User ID=TestUser1;Password=foo1;")) {
oCn.Open();
...
}
I found that type of naming in this article http://msdn.microsoft.com/en-us/magazine/cc163799.aspx
An entirely obsolete way of saying that "Cn" is an *o*bject.
I am afraid that it is a remainder of some hungarian dialect notation for an object.
In C# and .NET I consider this useless.
EDIT By the way I consider Hungarian notation containing type and/ore scope information useless in C#. I do like Apps Hungarian notation
In this case, "o" means object. It's an attempt at using the "systems" variation of hungarian notation.
There are two types of hungarian: Systems and Apps. Systems uses a prefix to identify the type of data stored. For example, the "i" in iCounter would indicate that the variable was an integer.
Apps hungarian took a completely different approach and specifies that the prefix should indicate the purpose of the data. For example, the "rw" in rwPosition would mean row.
The windows api used Systems hungarian. This led to a large number of other programmers also using it. The unfortunate aspect is that when changes were made to the api, they kept the old variable names even when the actual data type changed. This led to large amounts of confusion as to what data type a parameter to a given API function should be passed. Especially around various handles.
In the .Net coding guidelines, MS explicitly states that hungarian shouldn't be used. The reality is that they are talking about "Systems" hungarian; which I 100% agree with. "Apps" hungarian on the other hand has a ton of uses as you are describing the data, not the type.
At the end of the day just remove the "o". It adds nothing to the program.
Oh, and for interesting reading, check out Joel's take on this at: http://www.joelonsoftware.com/articles/Wrong.html
It probably means object like in some complex type that does not fit well with the same (ridiculous) convention that names strings strMyString and ints iMyInt etc.
This "rule" comes directly from How To Write Unmaintainable Code:
o_apple obj_apple
Use an "o" or "obj" prefix for each instance of the class to show that you're thinking of the big, polymorphic picture.
o is for object,
it's a, not very usefull, convention where by the type of the variable was incuded in the name, so a string was strWhatever. sometimes i even saw obj, i.e. objCn
As #Humberto suggested, appears to be the developer using Hungarian Notation.
When I started working as a programmer 10 years ago, the compagny I worked for was using a similar naming convention. I can't remember what is the convention name but I do remember that all the object instances had the "o" prefix, standing for Object.

Why don't Java, C# and C++ have ranges?

Ada, Pascal and many other languages support ranges, a way to subtype integers.
A range is a signed integer value which ranges from a value (first) to another (last).
It's easy to implement a class that does the same in OOP but I think that supporting the feature natively could let the compiler to do additional static checks.
I know that it's impossible to verify statically that a variabile defined in a range is not going to "overflow" runtime, i.e. due to bad input, but I think that something could be done.
I think about the Design by Contract approach (Eiffel) and the Spec# ( C# Contracts ), that give a more general solution.
Is there a simpler solution that checks, at least, static out-of-bound assignment at compile time in C++, C# and Java? Some kind of static-assert?
edit: I understand that "ranges" can be used for different purpose:
iterators
enumerators
integer subtype
I would focus on the latter, because the formers are easily mappable on C* language .
I think about a closed set of values, something like the music volume, i.e. a range that goes from 1 up to 100. I would like to increment or decrement it by a value. I would like to have a compile error in case of static overflow, something like:
volume=rangeInt(0,100);
volume=101; // compile error!
volume=getIntFromInput(); // possible runtime exception
Thanks.
Subrange types are not actually very useful in practice. We do not often allocate fixed length arrays, and there is also no reason for fixed sized integers. Usually where we do see fixed sized arrays they are acting as an enumeration, and we have a better (although "heavier") solution to that.
Subrange types also complicate the type system. It would be much more useful to bring in constraints between variables than to fixed constants.
(Obligatory mention that integers should be arbitrary size in any sensible language.)
Ranges are most useful when you can do something over that range, concisely. That means closures. For Java and C++ at least, a range type would be annoying compared to an iterator because you'd need to define an inner class to define what you're going to do over that range.
Java has had an assert keyword since version 1.4. If you're doing programming by contract, you're free to use those to check proper assignment. And any mutable attribute inside an object that should fall within a certain range should be checked prior to being set. You can also throw an IllegalArgumentException.
Why no range type? My guess is that the original designers didn't see one in C++ and didn't consider it as important as the other features they were trying to get right.
For C++, a lib for constrained values variables is currently being implemented and will be proposed in the boost libraries : http://student.agh.edu.pl/~kawulak/constrained_value/index.html
Pascal (and also Delphi) uses a subrange type but it is limited to ordinal types (integer, char and even boolean).
It is primarilly an integer with extra type checking. You can fake that in an other language using a class. This gives the advantage that you can apply more complex ranges.
I would add to Tom Hawtin response (to which I agree) that, for C++, the existence of ranges would not imply they would be checked - if you want to be consistent to the general language behavior - as array accesses, for instance, are also not range-checked anyway.
For C# and Java, I believe the decision was based on performance - to check ranges would impose a burden and complicate the compiler.
Notice that ranges are mainly useful during the debugging phase - a range violation should never occur in production code (theoretically). So range checks are better to be implemented not inside the language itself, but in pre- and post- conditions, which can (should) be stripped out when producing the release build.
This is an old question, but just wanted to update it. Java doesn't have ranges per-se, but if you really want the function you can use Commons Lang which has a number of range classes including IntRange:
IntRange ir = new IntRange(1, 10);
Bizarrely, this doesn't exist in Commons Math. I kind of agree with the accepted answer in part, but I don't believe ranges are useless, particularly in test cases.
C++ allows you to implement such types through templates, and I think there are a few libraries available doing this already. However, I think in most cases, the benefit is too small to justify the added complexity and compilation speed penalty.
As for static assert, it already exists.
Boost has a BOOST_STATIC_ASSERT, and on Windows, I think Microsoft's ATL library defines a similar one.
boost::type_traits and boost::mpl are probably your best friends in implementing something like this.
The flexibility to roll your own is better than having it built into the language. What if you want saturating arithmetic for example, instead of throwing an exception for out of range values? I.e.
MyRange<0,100> volume = 99;
volume += 10; // results in volume==100
In C# you can do this:
foreach(int i in System.Linq.Enumerable.Range(0, 10))
{
// Do something
}
JSR-305 provides some support for ranges but I don't know when if ever this will be part of Java.

Categories

Resources