1)根据我的书,is
运营商可以检查是否
仅当E
是引用转换,装箱或拆箱时,表达式E is type
(E
)才能转换为目标类型。由于在以下示例中is
未检查三种类型的转换中的任何一种,因此代码不起作用,但确实如此:
long l; // EDIT - I forgot to add this line of code in my initial post
int i=100;
if (i is long) //EDIT - in my initial post I've claimed condition returns true, but it really returns false
l = i;
2)
a)
B b;
A a = new A();
if (a is B)
b = (B)a;
int i = b.l;
class A { public int l = 100; }
class B:A { }
上述代码总是导致编译时错误“Use of unassigned variable”
。如果条件a is B
的评估结果为false
,那么b
将不会分配值,但如果条件为true
,则会{。}}。因此,通过允许这样的代码编译器无法知道b
语句之后的代码中if
的使用是否有效(由于不知道a is b
是否评估为true
或false
),但为什么要知道呢? Intsead为什么不能运行时处理这个?
b)但是如果相反我们处理非引用类型,那么编译器不会抱怨,即使代码是相同的。为什么?
int i = 100;
long l;
if (i is long)
l = i;
谢谢
答案 0 :(得分:6)
这与is
运算符无关。编译器发现有两个可能的路径,其中只有一个路径会将值赋给b
。
在处理值类型时,编译器知道l
被隐式初始化为值0
。
答案 1 :(得分:3)
真正的区别在于,int
案例中,您正在讨论明确指定字段(l
)。字段始终明确分配(即使没有=100
)。在B
案例中,您谈论的是局部变量(b
)的明确分配;局部变量 not 以明确分配的方式启动。
就是这样。
int i = 100; if(i is long)//返回true,表示转换是可能的
1:我认为这根本不会返回true
;对我来说,它显示了一个关于永远不会是真的IDE警告。查看反射器,编译器会完全删除此分支。我想编译器必须至少编译,理由是它(在理论上)可以进行框和测试。但它已经知道了答案,所以它会剪掉它。
2:我仍然得到“未分配的变量”编译器错误;由于“明确的任务”
答案 2 :(得分:2)
编译器行为正确 - 如果 使用未分配的变量,为什么编译时没有错误?如果b.l
未分配,则无法使用b
,因为编译器会检查是否存在未实例化b
的代码路径,这就是它抛出错误的原因...
答案 3 :(得分:2)
在你的代码中,B类派生自A.这意味着:
a is B // evaluates to false
b is A // evaluates to true
这意味着不会输入if
块的正文,也不会指定b。
答案 4 :(得分:2)
好的,MSDN在is
上说:
是运算符用于检查对象的运行时类型是否与给定类型兼容。
如果满足以下两个条件,则表达式的计算结果为true:
- 表达式不是 null 。
- 表达式可以转换为类型。也就是说,
(type)(expression)
形式的强制转换表达式将在不抛出异常的情况下完成。
这与1非常吻合,但2是另一个主题并且正确(想一想)。
但是,以下代码将0
写入输出:
int i = 1;
long l = 0;
if (i is long) {
l = i;
}
Console.WriteLine(l);
因此,is
MSDN文档中的注释似乎也是正确的:
请注意,is运算符仅考虑引用转换,装箱转换和取消装箱转换。 is运算符不会考虑其他转换,例如用户定义的转换。