Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
535 views
in Technique[技术] by (71.8m points)

c# - Why can TimeSpan and Guid Structs be compared to null?

I've noticed that some .NET structs can be compared to null. For example:

  TimeSpan y = new TimeSpan();
        if (y == null)
            return;

will compile just fine (the same with the Guid struct).
Now I know that stucts are value type and that the code above should not compile, unless there's an overload of operator == which takes an object. But, as far as I could tell there isn't.
I've looked at the class with Reflector, and also at the docs on MSDN.
The two of them do implement the following interfaces:

IComparable, IComparable<T>, IEquatable<T>

but, trying to implment the same Interfaces did not seem to help:

struct XX : IComparable, IComparable<XX>, IEquatable<XX> {
    public int CompareTo(Object obj) {
        return 0;
    }
    public int CompareTo (XX other){
        return 0;
    }
    public bool Equals (XX other){
        return false;
    }
    public override bool Equals(object value){
        return false;
    }
    public static int Compare(XX t1, XX t2){
        return 0;
    }
}

I'm using: .NET 2.0 Visual Studio 2005.

Does anyone has any idea what's the reason for this ? I am just trying to get a better understanding. This isn't an issue as I know I shouldn't compare structs to null anyway.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's the == operator.

The TimeSpan class has an overload of the equality operator:

public static bool operator ==(DateTime d1, DateTime d2)
{
     return (t1._ticks == t2._ticks);
}

This in itself doesn't make it possible to compare with null, but...

With the arrival of nullable types, each struct is implicitly convertible to its nullable type, so when you see something like

TimeSpan y = new TimeSpan();
if (y == null)
    return;

You don't see that this is happening:

TimeSpan y = new TimeSpan();
if ((Nullable<TimeSpan>)y == (Nullable<TimeSpan>)null)
    return;

Null gets the implicit conversion (implicit assignment?), but not all System.Object objects do:

TimeSpan y = new TimeSpan();
object o = null;
if (y == o) //compiler error
    return;

Okay, but the equality operator doesn't take nullable arguments, does it?

Well, msdn is of help here, stating:

The predefined unary and binary operators and any user-defined operators that exist for value types may also be used by nullable types. These operators produce a null value if [any of] the operands are null; otherwise, the operator uses the contained value to calculate the result.

So you effectively get a nullable implementation for each operator for free, with a fixed defined behaviour. The "contained value" mentioned above is the actual value the non-nullable operator would return.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...