8

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

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

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

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

4

2 回答 2

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() 的编译时类型,因此只有方法声明是相关的。

于 2012-05-23T19:41:22.603 回答
2

我对A的想法:

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

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

ISomething a = new MyOwnSomething();

你为什么想做这个?如果您明确地MyNewSomething实现ISomething了,那么您将不得不进行强制转换才能像ISomething在 var 上声明的 if 一样使用它。这里演员阵容仍然完成,但你看不到相当丑陋的:

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

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

于 2012-05-23T19:14:22.740 回答