So… What is this “var” thing? 5/5 (3)

posted in: Tutorials | 0

In programmable block scripts you will see a lot of code that declares an object as “var” and assigns something to it.

For example:

  1. var containerInvOwner = (IMyInventoryOwner)containerList[i];    
  3. var containerInv = containerInvOwner.GetInventory(inventoryIndex);  
  5. var containerItems = containerInv.GetItems();

What the “var” keyword does is tell the computer “you figure it out” and that’s exactly what the computer will do.

In the first example above, since we are explicitly “casting” containerList[i] to an IMyInventoryOwner type object, it’s a safe bet that the variable containerInvOwner will be an object of type IMyInventoryOwner.

In the second example, we are calling the GetInventory method on the containerInvOwner object to retrieve the nth inventory, in this case the number indicated by inventoryIndex.

In the third example we are calling the GetItems method on the containerInv object.

By looking at these statements there are a couple of things that we can figure out:

  1. containerInvOwner (the IMyInventoryOwner type) has a “list” of inventories. That’s why we have to give it an index, telling it which one of those inventories we want.
  2. The GetItems method, of the containerInv object will probably return a list of items. That’s why the name of the method is GetItems in the plural. C# developers tend to obey this rule.
  3. Whatever containerList[i] is, if this code works, then it means that containerList[i] is an object that can be cast to the IMyInventoryOwner type. If it is not possible to do the cast, you will get an error message to that effect saying that “Some.Assembly.Name.ObjectType cannot be cast to Some.Other.Assembly.Name.IMyInventoryOwner”
  4. As a general rule, you should always declare your variables explicitly. That’s the advantage of a strongly typed language.

    For example in that third example above, we don’t know, just by looking at the code, what type of object is returned by the GetItems method. GetItems returns a list of IMyInventoryItem objects (List<IMyInventoryItem>). So if we had the code the way it is and further down in the code we’re looping over the “containerItems” object and trying to use a method of the IMyInventoryObject, everything would be fine and it would work.

    Six months later I’m making some changes to this code and I decide I’m going to change the GetItems call to FindItem (because now I want it to find a particular item. The new third line would look like this:

    1. var containerItems = containerInv.FindItem(someContentId);

    That line will work fine. However, the “containerItems” variable is now of a different type. So further down in the code, where we were looping over the “containerItems” object, it’s going to fail. Because “containerItems” is now an IMyInventoryItem object instead of a list of IMyInventoryItem objects. The problem is that the code compiled with no problem because the compiler doesn’t know that “containerItems” is not going to be a list, because you didn’t declare it as such. It’s some variable object type that it won’t know until the code runs. Assuming you test your code, you would find this issue during testing. But not everyone does testing, at least not ALL the time.

    Bottom line: Use the strongly typed capabilities of the language. Your third line SHOULD be:

    1. List<MyInventoryItem> containerItems = containerInv.GetItems();

    Because in that case, if you changed the “GetItems()” to “FindItem(someContentId)”, it would tell you, immediately, that it’s wrong, because the compiler knows that the FindItems method returns a simple IMyInventoryItem and not a List<IMyInventoryItem>.

    Hope this helps!

    Please rate this post

Leave a Reply