隐式类型的限制

时间:2012-05-23 18:50:02

标签: c# types

在他的书中,Jon Skeet提到了对隐式打字的7个限制。我需要澄清最后两点:

A. 您希望变量具有的类型是初始化表达式的编译时类型。
B。初始化表达式不涉及声明的变量。

本书涵盖的材料与发布的顺序相同(C#3之前的C#2)。此时尚未引入C#4,因此我假设 A 未引用dynamic。那么,编译时类型何时与初始化表达式的执行时类型不同?

对于 B ,初始化表达式何时可以涉及声明的变量?

2 个答案:

答案 0 :(得分:3)

关于 B ,Henk给出了一个完美的答案(编辑:现在已删除),尽管我发现int x = x = 1;编译的特殊情况。 (我会认为 x 在初始化程序之后才被视为声明。哦,好吧。)他的答案是:

int x = x = 1;   // Compiles
var y = y = 2;   // Does not compile

关于 A 以及关于编译时类型何时与执行时间类型不匹配的问题,这里是一个不同的例子:

var foo = fooFactory.GetFoo();

... fooFactory上的那个方法实现为....

public FooBase GetFoo() {
    return new FooSubtype();
}

这里, foo 的类型是FooBase(可以是接口,抽象类或未密封的具体类),并且(没有强制转换)只有它的功能可用。显然,FooSubtype实现或继承自FooBase。

foo 在运行时保存的类型可以在这里辨别,因为我展示了GetFoo()的实现,但编译器没有检查它。实际上,实现可能甚至不可用(可能在另一个程序集中),也可能不同(可能是虚拟的)。要确定GetFoo()的编译时类型,因此确定 foo 的编译时类型,只有方法声明是相关的。

答案 1 :(得分:2)

我对 A 的想法:

并不是编译时与执行类型不同,因为即使执行类型与编译类型不同(就像在返回类型为抽象类型的任何方法中),也不能声明变量无论如何使用显式输入执行类型。

但您可能希望使用更抽象的静态类型声明变量,即使可以在编译时定义 real 动态类型。考虑例如:

ISomething a = new MyOwnSomething();

你为什么要这样做?如果你的MyNewSomething明确地实现了ISomething,那么如果在var上声明,你必须像使用ISomething一样进行强制转换。演员阵容仍然在这里完成,但你看不出相当丑陋:

var a = new MyOwnSomething();
((ISomething)a).Whatever();

一个更人为的例子是初始化代码可以在以后更改,但是您希望确保从此时起只使用a作为ISomething,并且永远不会看到详细信息MyOwnSomething类型或其可能实现的其他接口,以便初始化类型的更改不会破坏代码。