Wednesday, June 5, 2013

Value types vs. Reference Types

I won't claim to be an expert by any stretch of the imagination. However, I have learned a few tricks in dealing with the conversion of C++ libraries to C#.

Let me begin with a bit of background. I enjoy working with Unity3D. It has one small "problem", to work with C++ you have to buy the professional version, a small setback of 1500$. To counteract this problem, I've been working to convert a few C++ open source libraries to C#. Namely Recast Navigation and Bullet Physics.

"Why bother," you might ask? Well for one, I can't afford the 1500$ price tag for Unity3D. For another, taking apart the library helps me understand how it works. Furthermore, I can code Editor and Inspector enhancements for Unity3D to take advantage of the library.

Back to the topic at hand. A value type, when working with C++ and C#, is an object that contains its data directly. A reference type, on the other hand, is a reference to an object that contains its data. Let me explain it another way. If I hand you an apple, it would be a value type, I am passing the object directly to you. If I hand you a gift voucher for an apple, I still gave you an apple, but unlike the physical apple, when you go to get the apple for the voucher, it may not be the same one pictured on the voucher.

So what does that have to do with C++ and converting to C#?

In C++ everything is a value type, both class and struct. If you want to pass a reference to it, so you can modify it and give it back in the modified state, you have to do one of two things, either pass by reference by adding an &, or pass by pointer meaning you add a * at creation. Without this, when it gets to the function, if you make any changes, those changes are ignored when it gets back to the area that called it.

In C# classes are a reference type, this means that if I do A = B; A now points to the same apple B points to, if you want to make a copy of B to use with A, you have to create a new object, pass in the values of B, and give that to A. A = new Foo(B);

There is a handy little trick when it comes to C#. If you wish to always pass by value, that is A = B; gives a copy of A, you simply declare the class as a struct instead: public struct Foo{};

One minor word of caution, when you use structs, you cannot inherit from other structs or classes, only from interfaces. This could lead to code duplication if you are attempting to make a derived struct.

Anyway, this was today's lesson for me as I work through the conversion of Bullet Physics.

No comments: