Searching stuff goes here
I'm Chris Hannon, a senior software engineer in Salt Lake City, UT.
More about me...
Archive
Friday Quiz Day
By: Chris
Filed under: Quiz Of The Day

public class CustomEvent
{
public static event Action SomeEvent { add {} remove{} }
public static void RaiseEvent() { SomeEvent(); }
}

And it's called like this...

CustomEvent.SomeEvent += () => Console.WriteLine("Event called");
CustomEvent.RaiseEvent();

What will happen?

1) It will print “Event called”.
2) It won’t print anything because nothing’s been added to the event.
3) A compile-time error
4) A runtime-error
5) Some other thing that you tell me about.

Also, why did you pick your choice?

Show Answer

This will cause #3, specifically a compile time error on the SomeEvent() call within the RaiseEvent() method stating that the event can only appear on the left hand side of += or -=. The add/remove blocks within an event look like get/set blocks in a property, but they have a slightly different purpose. A property has two operations, get and set, but an event technically has three: Add to the list, remove from the list and call each item by iterating through the list. By including add/remove blocks, you are explicitly telling the compiler that you are taking over responsibility for how and where the delegates are stored. This also implicitly means that, because you know where you put those delegates, you are also now responsible for how they are called. To put that another way, imagine that your add block randomly assigned incoming delegates to fifteen separate hashtables. How would the compiler know where the delegates were if you called SomeEvent()? It has no idea, so it’s up to you now.

To help clarify, here's a sample implementation using the add/remove blocks.

public class CustomEvent
{
private static List<Action> storedDelegates = new List<Action>();
public static event Action SomeEvent
{
add { storedDelegates.Add(value); }
remove { storedDelegates.Remove(value); }
}
public static void RaiseEvent()
{
SomeEvent(); //This will cause a compile-time error

//An appropriate implementation would now have to do
//something like this, including account for any
//thread-safety issues (which this example does not do).
foreach (var action in storedDelegates)
action();
}
}



I do not claim that these originated from me (although the explanations are written by me). These have come from various people and places, including Eric Lippert, Jon Skeet, Joe Duffy, Stack Overflow and too many blogs and articles to count. Where I can remember, I will provide a link to where it came from. If I can't, forgive me (or provide me with a link to the original location and I will try to include it).
How are strings considered equal?
By: Chris
Filed under: Language And Use, Random Thoughts
Now that we’ve talked about equality, we can talk about how C# approaches string equality. Reference types, by default, do a reference comparison when using the == and != operators to check equality. The System.String class, however, does a value comparison. Why is that?

1. Strings are immutable

Almost every string that’s used in a given program, and every operation on a string, results in a brand new string. You can’t modify a string directly unless you jump through hoops, like using unsafe code, and so there’s not a whole lot of worth in comparing a string referentially: It’s most likely not the same one.

In some cases, such as constants (or if you explicitly enable it) the .Net runtime will intern strings for you. What that means is that every unique string that is to be interned is created only once and stored. All uses of a string with those characters will refer to the interned copy instead of creating their own.

2. String interning is the exception, not the norm

Interning strings is great for some situations, but it’s a tradeoff. You reduce your memory footprint and increase speed for comparisons by only performing reference comparisons, but you also have to deal with a slowdown in other areas. All of those strings will have to be stored somewhere for lookup and every new string will result in a potentially extensive search to see if it’s already been cached. Hashing the strings may be an option, but then the runtime may have to possibly deal with hashing, rehashing and organizing a potentially massive amount of strings.

The CLR, as implemented by Microsoft, does not intern strings by default but allows you to make that choice on your own. These are all implementation details, though. The real question is...

3. What does the user want?

When somebody wants to compare strings, are they usually asking “Are these two strings pointing to the same string in memory?” or are they asking “Do these two strings contain the same characters?”. It turns out that, as far as Microsoft’s research goes, the majority of the cases were asking whether the strings contained the same values.

What’s the difference between Equals() and using the != and == operators?

Not a whole lot, actually. Some people, including MSDN articles, have advocated the abandonment of the != and == operators when comparing strings, leaning more in favor of using the Equals() instance method for comparison. This is often stated as making your code’s intention more explicit.

I disagree for the following reasons.

Using an instance method for equality means that you need to be extremely sure that your instance is not null.

Granted, you may already have logic surrounding potential null values, such as when both strings are null, but this will make null checks mandatory.

The != and == operators use the static String.Equals() method as their implementation.

There is no additional overhead to using operators beyond the cost of a method call to the operator. They also cleanly preserve the intended semantics of the comparison without a lot of extra code. It is important to remember that != will include null, however, but so will using !someString.Equals(someOtherString) when someOtherString happens to be null and wasn't included in the previous logic around null values.

They both perform a value comparison.

In Java, one of the common issues that will bite you is the difference between the use of the == operator and the equals() method. The operator will perform a reference comparison but the equals() method will perform a value comparison. This is not the case in C#, both the operator and the method have the same meaning.

So why would I use Equals()?

The Equals() method has several overloads that determine how the string comparison is performed. That’s not to say that you can switch from value comparison to reference comparison, but you can specify whether the comparison should be done by using the ordinal sorting rules for the characters, whether it should take the casing of the letters into account and what influence a given culture should have on comparison.

These are all extremely useful things to be able to do and a useful way to refine your comparison. The bottom line for me is that you should use the != and == operators when you are performing a standard comparison, but if you really need to be specific then you should use Equals().
For a given value of 'equal'
By: Chris
Filed under: Random Thoughts
After posting the quiz about whether a double could ever be unequal to itself, I got into a discussion with a junior developer about it. He had a few misconceptions about equality that I thought might be beneficial to go into here. This isn't a transcript of that conversation but the Q&A format is useful for this.

A variable can never be unequal to itself because the bits that make up that variable are the same.

That depends strongly on your definition of equality. There are several types of equality. Value, or structural, equality is what you just named. Depending on the language, other kinds of equality may exist as well. For example, C# has referential, or identity, equality, meaning that two references point to the same thing, and what I like to call customizable equality, in that you can override the equality operators and tell the caller exactly how two instances relate.

That’s not actual equality, though. In a language like C, closer to the metal, you care more about the bits and types don’t necessarily relate directly to the bits, you’re only checking if bits are equal. All you have is value equality because of the disconnect between the bits and types.

That’s incorrect. Types are a way of reasoning about a chunk of memory. They take a shapeless blob of bits and say “I will treat these pieces of memory as something specific”. As soon as you’ve said that, you need to define how that “something” relates to other pieces of memory.

Value equality takes the easy first step and says “As long as all of the bits in my piece of memory are equal to all of the bits in this other piece of memory, we’re equal”. In C, though, you have pointers. What are pointers? They are a type. As such, they carry specific ways to treat equality. You can still compare all of the bits in the memory that is being pointed to. That is still value equality. Nothing’s changed there.

What’s been added? Referential equality. You can compare the addresses that are being pointed to and know that they are pointing to the same piece of memory, therefore they are equal.

How is that not value equality? You’re still comparing the bits in the address.

That’s true, but look at what’s being compared. The memory addresses! You never even touched any of the bits in your actual memory block! How do you know that the memory being pointed to is the same if you didn’t do a value equality check on all of the bits being pointed to? Because of referential equality. You’re still doing a value comparison, yes, but not of the original bits. You’re doing a value comparison of something that identifies those bits.

Imagine you have a box full of marbles, and you want to determine if another box of marbles has the same colors in the same amounts. You’d have to count every single one in each box and determine that each marble is the same. That’s a lot of work. On the other hand, say you attach an sticky note to the first box that’s labeled Box #1. You just identified the box.

If someone comes along and hands you a completely different sticky note that has Box #2 written on it, you can tell right off that they’re not talking about your box. The contents of the notes don’t match, even though the contents of boxes may be identifical. However, if they hand you a note that says Box #1, you know that your box and their box are the same because the contents of the note refer to the same thing.

So how does customizable equality fit in?

Imagine each box of marbles has a little piece of paper inside it. Box #1 has a paper that says “If another box has the same number of red marbles as this box, consider the boxes equal regardless of what other color distributions may exist in either box”. Based on that paper, a box might now be considered equal to another box regardless of the contents as long as the specific criteria are met.

Why have all of these different definitions for equality?

Because they all determine something different. You might as well ask “It’s all bits underneath, why have pointers to int as well as pointers to double?” and the response would be the same. It’s what you want to do with those bits that determines how you interact with them.

Are you verifying that two locations in memory are exactly the same? Use referential equality.
Are you verifying that two series of bits are exactly the same? Use value equality.
Are you verifying that two series of bits are semantically the same? Use customizable equality.
Memoization
By: Chris
Filed under: Random Thoughts
An important word to have in your vocabulary is memoization. That’s not a misspelling of memorization, it’s a different word but it has similar semantics about remembering. Memoization is a very specific way to cache things to avoid repeatedly doing the same thing over and over in a potentially more expensive way.

Why should I care? I’d like an example.

Okay. Wikipedia uses a factorial as an example, and generating the Fibonacci sequence would be another good example, but why are they good? What is it about those in particular that make them amenable to memoization?

They consistently return the same data for the same inputs. If you enter 4 into a factorial function, you are going to get 24 every single time. This consistency should be a clue that caching the results could possibly speed things up, especially if the calculations are a significant time or space burden.

This becomes even more useful if there are more than one way to potentially interact with the data. You could have a function that returns the Nth number in the Fibonacci sequence and another one that returns it every other number. Calculating the entire sequence every single time is a waste of your time and your caller’s time.

How would I cache calculations?

It’s important to distinguish, you’re not caching the calculations but the results for a given input. Whether you can trivially modify an existing class to provide caching to its callers or you have to build a caching mechanism around untouchable code, you are mapping input values to a previously calculated result. Writing caching into a class you can modify all you want is fairly easy, so let’s talk about steps you can take for caching results from code you can’t touch.

Let’s also define things so we have something concrete to talk about.

public class CalculatedInfo { /* Information that’s expensive to obtain */ }
public class User { /* Information about the user. Easy to obtain. */ }

public static CalculatedInfo Calculate(User user)
{
//Expensive calculations in untouchable code
}

As a first attempt, you could create a wrapper class to handle the caching.

public class CachedCalculations
{
private Dictionary<User, CalculatedInfo> cache =
new Dictionary<User, CalculatedInfo>();

public CalculatedInfo CachedCalculate(User user)
{
if (cache.ContainsKey(user))
return cache[user];
var info = Calculate(user);
cache.Add(user, info);
return info;
}
}

Fairly straightforward. The wrapper class contains a caching mechanism and, when called, it will check its local cache to see if we already have results. If it’s there, no harm done, we’ll just hand back the cached version. Otherwise, the expensive call is made and the result is added to the cache for possible lookup at some future point.

That’s very specific to the static Calculate method, though. We could apply this same pattern to any method that takes a type and returns another. Generics and delegates are your friend to make this applicable to more places.

public class CachedCall<T, U>
{
private Dictionary<T, U> cache = new Dictionary<T, U>();
private Func<T, U> originalCall;

public CachedCall(Func<T, U> originalCall)
{
this.originalCall = originalCall;
}

public U Call(T instance)
{
if (cache.ContainsKey(instance))
return cache[instance];
var result = this.originalCall(instance);
cache.Add(instance, result);
return result;
}
}

Much better. The pattern remains the same, with T and U in place of User and CalculatedInfo, but in addition we’re taking a delegate in the constructor that takes a T and returns a U. Creating an instance and handing the static Calculate method to it is minimal effort.

var cachedCall = new CachedCall<User, CalculatedInfo>(Calculate);
var someResult = cachedCall.Call(someUser);

That’s still a decent amount of code, though. We’re creating an entirely new class with a single method, just to cache results from a single method call. That seems a bit wasteful.

With C# delegates and lambdas, you can condense all of that down to a single memoization function. This is because lambdas have the ability to close over variables and use them when the lambda is invoked later on.

public static Func<T, U> Memoize<T, U>(Func<T, U> originalCall)
{
var cache = new Dictionary<T, U>();
return (instance) =>
{
if (cache.ContainsKey(instance))
return cache[instance];
var result = originalCall(instance);
cache.Add(instance, result);
return result;
};
}

And it would now be called like this.

var cachedCall = Memoize(Calculate);
var someResult = cachedCall(someUser);

The call site hasn’t changed a whole lot, but in the implementation we've removed the class, the constructor and the delegate field from the picture. So what's it doing? It takes a function from a T to a U, then creates a dictionary that maps T instances to U instances just like the class did. Where it differs is that it returns a delegate that closes over the function and the dictionary, taking them both along for the ride. A single method maps to a single method now without the extra baggage of an explicitly implemented class.
Monday Quiz Day
By: Chris
Filed under: Quiz Of The Day

double value = GetDouble();
if (value != value)
Console.WriteLine("Value is not equal to itself");

Is it possible to provide an implementation for GetDouble() that causes the Console.WriteLine() call to be hit? If so, what is it? If not, why not?

Show Answer

It is definitely possible. GetDouble() can return Double.NaN and this will satisfy the inequality check. So why is this allowed in the first place? C# implements the IEEE 754 specification for floating point calculations which states that NaN is not equal to anything, including itself. That begs the question, though. Why does the specification say that? I haven’t looked for an official statement, but it makes sense when you think about what NaN actually represents. NaN isn’t a number, it is the representation of an invalid number. How many ways can you think of to generate an invalid number? Is the square root of -1 the same imaginary thing as the square root of -2? It’s more straightforward to say that, because of this lack of reality surrounding the representation, it cannot be quantified and so is unequal to everything.* As far as C# goes, this is unfortunate because this makes sorting doubles with >, >=, ==, !=, <= and < fairly difficult. You can either use an inequality by using (!(value >= 0)) instead of (value < 0) or do a direct check with Double.IsNaN(value).**

*Additionally, as per the spec, there are quite a few bit patterns available to actually represent NaN. You can’t even be sure that your representation of NaN has the same bits as the NaN that you’re comparing it to, which would cause expressions like (value != Double.NaN) to potentially have even more strangeness associated with them.

** The implementation of Double.IsNaN() in the BCL actually does a (value != value) check after disabling the compiler warning about comparing a value to itself.


I do not claim that these originated from me (although the explanations are written by me). These have come from various people and places, including Eric Lippert, Jon Skeet, Joe Duffy, Stack Overflow and too many blogs and articles to count. Where I can remember, I will provide a link to where it came from. If I can't, forgive me (or provide me with a link to the original location and I will try to include it).
What does your object look like?
By: Chris
Filed under: Software
Visual Studio allows you to hover your mouse over a variable while debugging and it will show you a quick representation of the variable contents. By default, that representation is created by invoking the ToString() method on the given object. Due to how the base System.Object implementation of ToString() works, you may end up getting an object representation in your inspector that looks like { Some.Namespace.SomeType } unless that particular class hierarchy has overridden it.

That’s generally not very helpful, but you could always expand the node in the inspector and take a look at the details to get more information. Having useful information at a glance and obviating the need to expand nodes is a definite benefit, though, especially when you have an array of hundreds of elements and they all say { Some.Namespace.SomeType }. One approach you may decide to go with is to override ToString() yourself to provide a better way to quickly view your data.

public class SomeType
{
public int X;
public override string ToString()
{
return String.Format("X = {0}", this.X);
}
}


Now when you hover over an instance of SomeType, it will say "X = 0" instead of namespace and type name (assuming it hasn't had its X field set to anything yet explicitly). That’s perfectly fine and it will work as long as your code never needs to call ToString() and get something else. What if it does, though? What if you need additional information if you’re looking at this through the debugger, but it’s information that you would really rather not provide to any caller that may have access to public methods? You can’t reasonably expect to keep track of whether the debugger or specific code is calling you.

There is an attribute in System.Diagnostics called DebuggerDisplay that will solve this problem rather nicely.

[DebuggerDisplay("X = {X}, B = {B}")]
public class SomeType
{
public int X;
private int B;
public override string ToString()
{
return String.Format("X = {0}", this.X);
}
}


As far as the debugger is concerned, if the attribute is present then it takes precedence over the ToString() method. Inside the attribute constructor, you’ll notice that we have a formatted string that’s fairly similar to our previous string, but this one encloses an X and a B within curly braces.

The curly braces allow you to evaluate fields, properties or methods (and very simple expressions) using the ‘this’ that goes along with the type. In this case, it would print out the formatted string "X = 0, B = 0" and callers of ToString() would only get "X = 0".
Monday Quiz Day
By: Chris
Filed under: Quiz Of The Day

abstract class A<T>
{
public abstract void Foo(T x);
}

abstract class B<T, S> : A<T>
{
public virtual void Foo(S x) { Console.WriteLine("B"); }
}

abstract class C<T, S> : B<T, S>
{
public abstract override void Foo(T x);
}

class D : C<int, int>
{
public override void Foo(int x) { Console.WriteLine("D");
}


What happens if it’s called like this?

new D().Foo(1);

Does it:
1) Print out B
2) Print out D
3) Cause a runtime error
4) Cause a compile time error
5) Do some unidentified other thing

Lastly, why do you think that?

Show Answer

This will cause a runtime error, with the message “Method ‘Foo’ in type ‘D’ from assembly ‘SomeAssembly’ does not have an implementation”. Why did it compile then? A defines a Foo that takes a T. That’s fine. B inherits and creates a method also named Foo that takes an S. This is introducing a bad thing. This method could potentially shadow the Foo in A. I say ‘potentially’ because it will only be the same method signature if the type parameters T and S are the same.

At this point, C overrides a method in B or A that takes a type of T. The only method in the type hierarchy that matches that signature is A.Foo, so that’s what it overrides. So far so good. But D… overrides a Foo, closes the type and sets both type parameters to int. So which method does that override? It actually overrides C.Foo, because that’s the closest ancestor to the current class. Perfect! The compiler has two separate methods, but it knows which one to call so we’re good.

That’s why it compiles. The CLR specification, however, states that a type will be considered invalid if it contains two methods that have the same name and signature after generic type substitution. D now contains two methods named Foo that take an int and return void, which means that the type is invalid at runtime.


For the original post of this problem, feel free to wander over to Sam Ng’s blog or read a related Stack Overflow answer by Eric Lippert.

I do not claim that these originated from me (although the explanations are written by me). These have come from various people and places, including Eric Lippert, Jon Skeet, Joe Duffy, Stack Overflow and too many blogs and articles to count. Where I can remember, I will provide a link to where it came from. If I can't, forgive me (or provide me with a link to the original location and I will try to include it).
Thinking About Lambdas
By: Chris
Filed under: Uncategorized
Lambda expression are gaining traction in more of the mainstream languages. They’ve been in C# for a few years now, lambdas are officially coming in Java 8 and the C++ 11 specification has already been finalized to include lambdas.

What’s a lambda?

At least a handful of people over the years have asked me to explain lambdas to them. It can be a tricky thing to wrap your head around, especially if you’ve come from a background in languages without first-class functions, but even with a familiarity of delegates it can throw you for a second. At this point, there are quite a lot of resources available regarding C# lambdas and their syntax, but I haven’t seen many of those provide an easy way to shift your mind over to that way of thinking. For what it's worth, here’s how I’ve attempted to do that for those people who’ve asked me.

Let’s say you have a library method that determines whether a number is greater than ten.

public bool IsGreaterThanTen(int value)
{
return value > 10;
}

That’s a pretty boring method, but let’s go with it. Presumably, if you have this method, you also might want to apply that to an array of numbers and pick out all of the numbers greater than ten.

public List<int> GetNumbersGreaterThanTen(int[] array)
{
var results = new List<int>();
for (int i = 0; i < array.Length; i++)
{
if (IsGreaterThanTen(i))
results.Add(i);
}

return results;
}

That works, but it’s very specific to the library function. At some point in the future, we may also want to get numbers that are higher than twenty. We may want only numbers between five and thirty-eight. It’s conceivable that we could want to get any combination of things out of the list! Each of those would require a method that looks exactly like this except for a slightly different method call in the middle. Could we abstract the method call out and make this more general?

The crux of the specific behavior happens to be the call to IsGreaterThanTen. Instead of directly calling it, we should allow any method with that signature to be passed in as an argument and call that instead, giving us a little bit more flexibility.

What does that look like?

public List<int> GetNumbers(int[] array, Func<int,bool> shouldTake)
{
var results = new List<int>();
for (int i = 0; i < array.Length; i++)
{
if (shouldTake(i))
results.Add(i);
}

return results;
}

Func<> is a delegate. It represents a method that returns a non-void result. In this case, it takes an int as a parameter and returns true or false. How do we call GetNumbers?

Func<int,bool> greaterThanTen = IsGreaterThanTen;
var results = GetNumbers(someArray, greaterThanTen);

Handwaving away a lot of extra details, assigning the IsGreaterThanTen method to the variable essentially means that when we call greaterThanTen() it will really call the method IsGreaterThanTen.

It’s the same method call as before, we’re just passing the call into GetNumbers instead of explicitly making the call inside, but now there’s a layer of abstraction. We can pass any method that takes an int and returns a bool to the GetNumbers method and have it execute as the deciding factor. Reusing the GetNumbers call with different criteria would be as simple as creating a new method and passing it in.

That’s great! But... that also means that we could potentially have a lot of helper methods lying around. What if we have a one-off where we want to filter the list on numbers greater than twenty five for a special case? What about greater than fifty two? We’d have to create another method, and another method, and pretty soon we’ll have an entire file full of these little special cases.

Declaring the method local to where it’s used could solve this.

Func<int,bool> greaterThanTwentyFive = (int value) =>
{
return value > 25;
};
var results = GetNumbers(someArray, greaterThanTwentyFive);

We’re creating a delegate that takes an int as a parameter and returns an bool. The big arrow sign (e.g. =>) indicates that this is a lambda. It just separates the parameter list from the body of the method. Now the greaterThanTwentyFive method isn’t floating around for anyone to use, it’s defined inside the current method and stored in a local variable.

So how does that help us? We traded a method that anyone can use for a local method and we still used the same number of lines of code. It reduces the visibility but that still doesn’t seem like a winning strategy overall.

It turns out that the curly braces and the return keyword are optional in a lambda if it only uses one line. We could easily do this.

Func<int,bool> greaterThanTwentyFive = (int value) => value > 25;
var results = GetNumbers(someArray, greaterThanTwentyFive);

That’s a bit better. It’s local to the method, yes, but it’s just a single line. Condensing things even further, we don’t have to explicitly say that it takes an int because it can figure that out based on the fact that it’s being assigned to a Func<int, bool>.

Func<int,bool> greaterThanTwentyFive = (value) => value > 25;

And because it’s a single parameter, we can omit the parentheses around the parameter list as well.

Func<int,bool> greaterThanTwentyFive = value => value > 25;

As a further way to condense the lambda, there’s no reason at all to store it in a separate variable when it can figure everything out from the method arguments.

var results = GetNumbers(someArray, value => value > 25);


That’s nice, but I don’t want to hardcode the 25. Do I have to put another parameter in both GetNumbers() and the lambda so I can pass this in?

No! In fact, that would be extremely cumbersome to deal with. It would be better to close over the variables that you want to use. You can use parameters and local variables in much the same way as you would in other locations in your method.

public int[] GetGreaterNumbers(int[] someArray, int minimum)
{
return GetNumbers(someArray, value => value > minimum);
}

We closed over the ‘minimum’ parameter and just used it directly inside the lambda.

Can we abstract this away from int? I want to reuse this for any type.

Yes! In fact, that’s an extremely useful way to reuse this kind of code. We just need to make the code generic.

public List<T> GetSelectedItems<T>(T[] array, Func<T,bool> shouldTake)
{
var results = new List<T>();
for (int i = 0; i < array.Length; i++)
{
if (shouldTake(i))
results.Add(i);
}

return results;
}

This concept is actually a very rough basis for a lot of the IEnumerable<T> extension methods, like Any() or Where(), and we could follow a similar pattern with ours.

public IEnumerable<T> GetSelectedItems<T>(this IEnumerable<T> sequence, Func<T, bool> shouldTake)
{
foreach (var item in sequence)
{
if (shouldTake(item))
yield return item;
}
}

Friday Quiz Day
By: Chris
Filed under: Quiz Of The Day

public static Action call;

public static void First()
{
call -= Second;
}

public static void Second()
{
Console.WriteLine("Second was run");
}

If you call this code in the following manner, does it print anything to the console when it's run? Why or why not?

call += First;
call += Second;
call();

Show Answer

It will print “Second was run” because both First and Second will be called. This is because multicast delegates are immutable. The -= and += operators won’t affect the original version but will create an immutable copy that contains the requested addition or subtraction. It will then reassign that copy to the same variable, which merely gives the impression that it’s mutating. In this way, making changes to the delegate in the middle of the call does not affect the current multicast execution, it’s not even dealing with the same set of delegates.

This is also why you could have potential race conditions around triggering events and why code that is wired up to an event needs to be robust in the face of invalid or unexpected state. For more information on that particular problem, see Eric Lippert’s blog.


The original question was taken from Stack Overflow.

I do not claim that these originated from me (although the explanations are written by me). These have come from various people and places, including Eric Lippert, Jon Skeet, Joe Duffy, Stack Overflow and too many blogs and articles to count. Where I can remember, I will provide a link to where it came from. If I can't, forgive me (or provide me with a link to the original location and I will try to include it).
Friday Quiz Day
By: Chris
Filed under: Quiz Of The Day

int[] array = { 0 };
array[array[0]--] = array[array[0]++];

Does this throw an IndexOutOfRangeException at runtime? Why or why not?

Show Answer

Most definitely, but not on the left hand side. Order of evaluation in C# happens in a left to right manner, and the left hand expression uses a post-decrement, so the following happens.

Evaluate the left side

1. Get the value of array[0] and remember it.
(This will be 0)
2. Use the value from Step 1 as the array indexer for assignment.
(Indexing into the array at 0)
3. Increment the remembered value from Step 1, changing the value stored in array[0].
(Writing -1 at array[0])

Evaluate the right side

1. Get the value of array[0] and remember it.
(This will be -1)
2. Use the value from Step 1 as the array indexer.
(This will be -1)
3. Get the value of array[-1] for assignment to the left hand side.
(This will throw an IndexOutOfRangeException)
4. Increment the remembered value from Step 1, changing the value stored in array[0].
(This would store 0 if it actually reached this point)

It’s important to note that this would not throw an exception if the right hand side had been array[++array[0]] instead, making the increment apply prior to the actual indexing attempt.


I do not claim that these originated from me (although the explanations are written by me). These have come from various people and places, including Eric Lippert, Jon Skeet, Joe Duffy, Stack Overflow and too many blogs and articles to count. Where I can remember, I will provide a link to where it came from. If I can't, forgive me (or provide me with a link to the original location and I will try to include it).