开发者

Why doesn't is operator take in consideration if the explicit operator is overriden when checking types?

Consider this code sample:

public class Human {    
    public string Value { get; set;}
}
public class Car { 

    public static explicit operator Human (Car c) { 

        Human h = new Human();

        h.Value = "Value from Car";
        return h;
    开发者_如何学JAVA}
}

public class Program { 
public static void Mani() { 
        Car c = new Car();

        Human h = (Human)c;
        Console.WriteLine("h.Value = {0}", h.Value);
        Console.WriteLine(c is Human);
}
}

Up I provide a possibility of an explicit cast from Car to Human, though Car and Human hierarchically are not related! The above code simply means that "Car is convertible to human"

However, if you run the snippet you will find the expression c is Human evaluates to false! I used to believe that the is operator is kinda expensive cause it attempts to do an actual cast that might result in an InvalidCastException. If the operator is trying to cast, then the cast should succeed as there's an operator logic that should perform the cast!

What does "is" test?

Does test a hierarchical "is-a" relationship?

Does test whether a variable type "is convertible to" a type?


The is operator tests for an actual type relation, not for 'can cast'. Rightfully so.

As for the 'how does it do it' part: I don't know but I assume there are more efficient ways (reflection) to test for family ties than letting it come to an exception.


Note that the is operator only considers reference conversions, boxing conversions, and unboxing conversions. Other conversions, such as user-defined conversions, are not considered.

http://msdn.microsoft.com/en-us/library/scekt9xw(VS.80).aspx


As an addition to Henk's answer, I guess reflection should provide some method to check whether a user-defined cast exists.


The is operator never throws exceptions. It does the exact same thing as the related as operator except that it converts the result to a boolean. The is and as operators are very fast if you are doing an up-cast because the CLR in that case knows what types are compatible. If you are down-casting the cast is a bit slower.

Normal casting (i.e. Mytype o2 = (Mytype) o1;) does the same as the as operator but it may throw an InvalidCastException.

In your case where you have defined an explicit cast operator you have to use the normal cast operator.


It makes sense:

You are checking the car object to a human type. If they'are the same or the same kind (if object inherits the human type) then it would have return true.

The keyword is therefore used to check for type compatibility, usually before casting (converting) a source type to a destination type in order to ensure that won't cause a type-cast exception to be thrown. Using is on a null variable always returns false.

from this link

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜