代码之家  ›  专栏  ›  技术社区  ›  Ahmed

如果在检查类型时重写显式运算符,为什么不考虑is运算符?

c#
  •  1
  • Ahmed  · 技术社区  · 14 年前

    考虑以下代码示例:

    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;
        }
    }
    
    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);
    }
    }
    

    向上我提供了一个从汽车到人类的显式转换的可能性,尽管汽车和人类的层次结构是不相关的!上面的代码仅仅意味着 “汽车可以改装成人”

    但是,如果运行代码段,您将找到表达式 c is Human 计算结果为假! I used to believe that the is operator is kinda expensive cause it attempts to do an actual cast InvalidCastException . 如果操作符尝试强制转换,那么强制转换应该成功,因为有一个操作符逻辑应该执行强制转换!

    是否测试层次结构 “是-a”
    “可转换为” a型?

    5 回复  |  直到 14 年前
        1
  •  3
  •   Henk Holterman    14 年前

    is 运算符测试实际类型关系,而不是“can cast”。当然如此。

    至于“它是如何做到的”部分:我不知道,但我认为有更有效的方法(反思)来测试家庭关系,而不是让它成为一个例外。

        2
  •  0
  •   richardwiden    14 年前

    注意,is运算符只考虑引用转换、装箱转换和取消装箱转换。不考虑其他转换,例如用户定义的转换。

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

        3
  •  0
  •   chiccodoro    14 年前

    作为Henk答案的补充,我想反射应该提供一些方法来检查是否存在用户定义的强制转换。

        4
  •  0
  •   Jakob Christensen    14 年前

    这个 is as 作为 如果您正在执行向上转换,运算符的速度会非常快,因为在这种情况下,CLR知道哪些类型是兼容的。如果你投得不好,投法会慢一点。

    正常铸造(即。 Mytype o2 = (Mytype) o1; 作为 运算符,但它可能引发InvalidCastException。

    在定义了显式cast运算符的情况下,必须使用普通cast运算符。

        5
  •  0
  •   VoodooChild    14 年前

    这很有道理:

    因此,关键字用于检查 将源类型转换为 目的地类型以确保 不会导致类型转换异常 被扔掉。使用的是空值

    this link