Archive for the ‘C#’ Category.

C++ const correctness beats the .NET/Java alternatives

The C++ const keyword is a powerful tool. It basically allows you to pass a pointer or reference that can only be used to call const methods. ie: You can implement a mutable class and then pass an immutable reference to that class (the keyword also does other things, but that’s not what I’m writing about). This defines a much stronger contract. When a function asks for a pointer to an instance of Foobar it can promise that it will not change that object. For example:

#include <string>
#include <iostream>
 
// Here's a piece of a class with one const method and one non-const method
class Person
{
public:
	std::string getName() const { return name; }
	void setName(std::string newName) { name = newName; }
private:
	std::string name;
};
 
// This function asks for a references to a person but promises not to change the object
void doSomethingWithPerson(const Person &person)
{
	std::cout << person.getName(); // <-- this is fine
	person.setName("hello"); // <-- COMPILE ERROR
}
 
int main(int argc, char *argv[])
{
	Person myPerson;
	myPerson.setName("Foobar");
 
	doSomethingWithPerson(myPerson);
 
	return EXIT_SUCCESS;
}

I love code like this. When I call doSomethingWithPerson() I know for sure that it will not change the object (assuming I have properly labelled my const methods). This is an area where I generally think of languages like Java or C# as being superior to C++. We commonly assume that these higher level languages are better at protecting programmers from themselves (or other programmers) but here it is not the case. You can achieve a similar result by creating an immutable class, but what if you do want to change it in other cases? Maybe you want to pass an immutable instance to one function and a mutable instance to another. This can surely be implemented, but it likely involves creating a second class (maybe a read-only subclass) which is kind of a pain. In reality developers often do not bother to create read-only versions of classes where it is warranted, but they will take the time to put const where it is needed.

After a lot of time just working in .NET I have returned to doing some C++ programming on a hobby project. Suddenly I feel dirty when I go back to .NET and start passing objects as function parameters willy nilly without using a const reference. It really is amazing how programming in different languages can change the way you think.

.NET reflection: don’t rely on the call stack, it’s a trap!

In recent memory I have twice tried to write reflection code that seemed totally badass at the time but turned out to be just plain bad. One case involved the use of GetCallingAssembly() and the other involved navigating the stack trace with stackTrace.GetFrame(1). While there is nothing inherently wrong with these functions (ie: they can be used perfectly fine for logging or debugging) you absolutely cannot depend on a specific result due to runtime optimizations by the .NET JIT compiler. For example, imagine A calls B and B calls C. If C runs GetCallingAssembly() then you would expect to get the assembly of B; however, if function B gets inlined in A (which is not uncommon) then technically A is directly calling C, and you will actually get A as a result! In fact, if you check the MSDN documentation they even warn you about this:

If the method that calls the GetCallingAssembly method is expanded inline by the just-in-time (JIT) compiler, or if its caller is expanded inline, the assembly that is returned by GetCallingAssembly may differ unexpectedly.

The documentation for GetExecutingAssembly() has no such warning, but just to be safe I prefer to be explicit with something like this: myObject.GetType().Assembly

Are you sure you want List? Maybe you really want HashSet

I often find that I get so used to using List<T> for my collections that I forget to consider whether it is really the right tool for the job. If the collection is not ordered, and you don’t want duplicates then there are a lot of benefits to using HashSet<T>. For example with List<T> you’ll find yourself writing code like this:

if (!myCollection.Contains(newString))
{
    myCollection.Add(newString);
}

This is a little verbose and it’s also inefficient. Every time you call Contains() the entire collection has to be scanned. With a HashSet<T> set operations are optimized and the code is simpler:

myHashSet.Add(newString);

The other benefit is that you actually enforce the no duplicate rule since adding the same element more than once will have no effect. Here’s what the MSDN documentation says about HashSet<T>:

The HashSet(Of T) class provides high-performance set operations. A set is a collection that contains no duplicate elements, and whose elements are in no particular order.

In practice I am finding that there are actually a lot of scenarios when I really want a set and not a list. So the next time you create a collection, think about whether you can use a HashSet.

The trouble with properties

Properties are supposed to provide encapsulation for your getter and setter logic, but they really don’t enforce it. Here’s what I mean:

private String _title;
 
public String Title
{
    get
    {
        // do custom getter stuff here
        return _title;
    }
    set
    {
        // do custom setter stuff here
        _title = value;
    }
}

The private field _title is the backing store for the property Title. The issue is that I don’t want to manually create this backing store, and I really don’t want it to be available anywhere in the class. I want to force anyone who edits this class to modify the value using the property, not the backing store. You don’t have to create a backing store with a default property like this:

public String Title { get; set; }

This is convenient, but it beats the point entirely. I specifically want to avoid the backing store when I have custom logic in either the getter or the setter. Currently in C# and VB (and every other language I can think of for that matter) there is no way to force the use of the property internally. I think it would be ideal to have an automatic backing store that is only accessible within the getter and setter.

Am I crazy?

Visual Basic 10 properties still lag behind C#

Up until Visual Studio 2010, simple property definitions were always ridiculously verbose. For example:

    Private _title As String
    Public Property Title() As String
        Get
            Return _title
        End Get
        Set(ByVal value As String)
            _title = value
        End Set
    End Property

That’s 9 lines of code just to make a simple string property. Luckily, in VB 10 we will be able to write these simple properties in one line:

    Public Property Title As String

This is great, but what if things get a little more complicated? Obviously this syntax just uses the default getter and setter, both of which have the same scope. When I write my properties I like avoid using ReadOnly and instead make the setter private so that I can still encapsulate the setting code within the class. With VB 10 you still have to define the property the old way in order to do this:

    Private _title As String
    Public Property Title() As String
        Get
            Return _title
        End Get
        Private Set(ByVal value As String)
            _title = value
        End Set
    End Property

But now it’s back to 9 lines just because I wanted the setter to be private. In C#, programmers have the luxury of writing properties like this:

    public string Title { get; private set; }

Furthermore, neither language allows you to use a default getter and custom setter (or vice versa) probably because it would make it difficult for them both to use the same backing store, but that’s a whole other tangent. Overall, the new abbreviated syntax for properties in VB 10 is great for the simple cases, but you have to revert to the old, verbose method if you want to deviate from the default in even the slightest way.

LINQ to SQL Gotcha #6: Delete, Save, Insert, CRASH

If you keep the same entity around after it has been deleted and SubmitChanges() is called then you can run into an InvalidOperationException if you try to insert it again.

var data = new DataClasses1DataContext();
var user = new User() { userName = "foo", password = "bar" };
 
data.Users.InsertOnSubmit(user);
data.SubmitChanges();
 
data.Users.DeleteOnSubmit(user);
data.SubmitChanges();
 
data.Users.InsertOnSubmit(user);
data.SubmitChanges();

Here you will actually get an exception on the second InsertOnSubmit() because the data context remembered the entity and will no longer allow you to attach it for some reason. Once an entity has been deleted from a data context it can never go back. To get around this you need to either insert the entity to a different data context or copy the data to a new instance of the same entity class and then insert it. This has been confirmed here.

Note: You are free to call DeleteOnSubmit() and then InsertOnSubmit() all you want as long as you never call SubmitChanges().