Casts using “as” (Pitfalls and Best Practices to Prevent Them #5)

Well – “as” is faster to type than a “real” cast using two brackets and has the same result. Really?

C# provides several ways to cast one type to another one. The two used in most cases are the “([Targettype]) [Variable]” and the “[Variable] as [Targettype]” notations. Many developers see them as equivalents, some even prefer “as” because it does not throw an exception when the cast fails.

Example

Let’s say we have a variable called obj of type Object and we want to cast it to an IFoo so we can call IFoo.Bar:

object obj;
//...
(obj as IFoo).Bar();

Read the rest of this entry »

No Interface Without Contract? – Part 5: Using Microsoft Code Contracts

Microsoft Code Contracts? Get started using them!

In the previous part we had a first look on Microsoft Code Contracts. This part will help us getting started using them.

Download and Installation

To use MS Code Contracts you need at least the Standard Edition of Visual Studio 2008 (VS 2010 is also supported).

Read the rest of this entry »

No Interface Without Contract? – Part 4: Writing down Pre- and Postconditions

Contracts are important – we already saw this. What can we do that we always see them when coding?

In the previous part, we formulated pre- and postconditions for a sample class. However, we only have written them down in plain text.

So we are now finding out how to specify them in a more comfortable (and elegant of course 😉 ) way.

I will introduce five possibilities: Documentation, Exception / Assert based, Custom Checker Class, Attributes and Code Contracts.

Read the rest of this entry »

No Interface Without Contract? – Part 3: Finding Pre- and Postconditions

“If you give me a string not beeing null or empty, I will give you a number greater zero” – Pre- and Postconditions made easy.

In the previous part, we found out that pre- and postconditions improve the quality of our code.

Note: I primary announced that part 3 is about writing them down. However, while writing I realized that it is better to split up this part.

Example

Let’s take a look at our sample class first:

Read the rest of this entry »

No interface without contract? – Part 2: About Pre- and Postconditions

Pre- and Postconditions: What they are, why you should use them and how they help you.

In the last part, the result was that we need something helping us to specify those kinds of “Implementation-Requirements”.

I already alluded to Pre- and Postconditions.

Read the rest of this entry »

No interface without contract? – Part 1: Why plain interfaces aren’t enough

An interface is an interface – why this is not always right.

What is an interface?

Wikipedia says:

Interface generally refers to an abstraction that an entity provides of itself to the outside.

In C#, interfaces are realized using the interface keyword. It is explained as follows:

An interface contains only the signatures of methods, delegates or events. The implementation of the methods is done in the class that implements the interface, […]

You have to separate between these two definitions:

Read the rest of this entry »

Pitfalls and Best Practices to prevent them #2: Operator priority

Example

class Program
{
    static void Main(string[] args)
    {
        Foo foo = new Foo();
        foo.Test = "Baz";

        foo.Bar(null);
    }
}

public sealed class Foo
{
    public string Test
    {
        get;
        set;
    }

    public void Bar(Foo other)
    {
        this.Test += "Value:" + other == null ? "<null>" : other.Test;
    }
}

What does it do?

The method Bar contains an expression using the tertiary operator to handle the case that other is null.

In this case “<null>” is appended instead of the value of other.Test.

However, this is only what the code should do. In fact, there occurs a NullReferenceException.

Doku says

C# Language Specification (7.2.1: Operator precedence and associativity):

The following table summarizes all operators in order of precedence from highest to lowest:

Section Category Operators
7.5 Primary x.y f(x) a[x] x++ x– new typeof default checked unchecked delegate
7.6 Unary + – ! ~ ++x –x (T)x
7.7 Multiplicative * / %
7.7 Additive + –
7.8 Shift << >>
7.9 Relational and type testing < > <= >= is as
7.9 Equality == !=
7.10 Logical AND &
7.10 Logical XOR ^
7.10 Logical OR |
7.11 Conditional AND &&
7.11 Conditional OR ||
7.12 Null coalescing ??
7.13 Conditional ?:
7.16, 7.14 Assignment and lambda expression = *= /= %= += -= <<= >>= &= ^= |= =>

 

Problem

I already mentioned: There occurs a NullReferenceException.

Let’s take a closer look to the problematic line:

this.Test += "Value:" + other == null ? "<null>" : other.Test;

As the += operator has a lower precedence than the others, we can say: The following part is executed before the assignment:

"Value:" + other == null ? "<null>" : other.Test;

What about this part now? Well, as the +-operator has a higher precedence than the ?:-operator, we are now able to write what the compiler actually does in another way:

string temp = "Value:" + other; //Will always be "Value:ConsoleApplication1.Foo"
temp = temp == null ? "<null>" : other.Test; //As temp is never null, temp will be other.Test
this.Test += temp;

You should see the problem in the second line now: other.Test is accessed irrespective of its “nullstate”.

How to solve?

As always (:-)) there is a simple solution: Make clear what you want by using brackets:

this.Test += "Value:" + (other == null ? "<null>" : other.Test);

The code not only gets “right” now, it’s also easier to understand.

Generalization / Best Practice:

In (complex) statements, do not hesitate to use brackets; better “safe than sorry”. They make the code clearer and prevent errors originating in misjudged operator precedence. Two very important cases are the ?:-operator and all logical operators.

DotNetKicks Image
Posted in Pitfalls. Tags: , , . Comments Off on Pitfalls and Best Practices to prevent them #2: Operator priority