C# Enum Quirks

I’ve been slashing out C# code since 2000. Just today I discovered something totally new to me.

Would you reckon that this test is valid?

public enum Direction
{
	Left,
	Right 
}

[TestClass]
public class EnumQuirks
{
	[TestMethod]
	public void Cast_any_number_to_enum()
	{
		Direction direction = (Direction)5;
		Assert.AreEqual(5, (int)direction);
	}
}

In fact, it is. An enumeration can be casted to its underlying data type, of course; by default, this is an Int32. What I hadn’t realized is that the conversion works the other way too. Any integer value can be assigned to an enum, whether the values are defined or not. In order to safely assign a numeric value, the result of Enum.IsDefined can be evaluated.

But it gets weirder. In order to convert a string value into an enum, there’s the TryParse method. But when it tries parsing really hard, look what it can do:

[TestMethod]
public void TryParse_accepts_any_number_in_string()
{
	string value = "5";
	Direction direction;
	bool canParse = Enum.TryParse(value, out direction);
	Assert.AreEqual(5, (int)direction);
	Assert.IsTrue(canParse);
}

This is even documented:

Enum.TryParse: Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.

It converts the numeric value too. And since there is no check if there is a constant defined for any numeric value, any string that can be parsed to a number is valid.

Lesson learned: you can’t trust assignments to enumerations without checking Enum.IsDefined. And if there’s code out there that parses string coming from an insecure source (like an web request), you can’t rely on Enum.TryParse.

Advertisements
About

Christian is a software architect/developer. He lives in Germany, reads a lot, and likes cycling.

Posted in Coding

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: