Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 隐式类型的限制_C#_Types - Fatal编程技术网

C# 隐式类型的限制

C# 隐式类型的限制,c#,types,C#,Types,在他的书中,Jon Skeet提到了隐式打字的7个限制。我需要澄清最后两个问题: A.希望变量具有的类型是初始化表达式的编译时类型。 B.初始化表达式不涉及所声明的变量 这本书以与发行相同的顺序(C#3之前的C#2)覆盖材料。此时还没有引入C#4,因此我假设A不是指动态。那么,编译时类型何时与初始化表达式的执行时类型不同 至于B,什么时候初始化表达式可以包含所声明的变量?我对A的看法: 编译时与执行类型并不是不同的,因为即使执行类型与编译类型不同(就像任何返回类型为抽象类型的方法一样),也不能通

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

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

这本书以与发行相同的顺序(C#3之前的C#2)覆盖材料。此时还没有引入C#4,因此我假设A不是指
动态
。那么,编译时类型何时与初始化表达式的执行时类型不同


至于B,什么时候初始化表达式可以包含所声明的变量?

我对A的看法:

编译时与执行类型并不是不同的,因为即使执行类型与编译类型不同(就像任何返回类型为抽象类型的方法一样),也不能通过显式类型声明具有执行类型的变量

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

ISomething a = new MyOwnSomething();
你为什么要这么做?如果您的
MyNewSomething
显式地实现了
ISomething
,那么如果在变量上声明,您将不得不进行转换,以便像使用
ISomething
一样使用它。在这里,转换仍然完成,但您没有看到非常丑陋的:

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

一个更人为的例子是,初始化代码可以在以后更改,但您希望确保从现在开始,您只将
A
用作
ISomething
,而从不查看
MyOwnSomething
类型的详细信息或它可能实现的其他接口,因此,对初始化类型的更改不会破坏代码。

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

对于B?@WiktorZychla来说,var x=2*x不是一个很好的例子吗?@WiktorZychla-也不会使用显式类型进行编译另一个示例是一个变量,它被初始化为一种特定类型,但在其生命周期中可能有其他不太特定的类型@phoog:没错。这就是显式声明用更好的语法为您解决的问题。我投票赞成一个非常清楚的解释,但在这种情况下,显式声明也必须是
FooBase a
,而不是
FooSubtype a
,因此使用显式声明没有任何好处。我认为限制是指什么时候更喜欢明确声明。谢谢你的投票,@AlejandroPiad!但我认为“限制”指的是何时可以隐式声明。也就是说,如果您的初始化表达式违反了其中之一,那么您就不能使用隐式声明。是否被优先考虑是另一个有不同意见的问题。这很公平。这个词用错了。我想说的是,当隐式打字给你带来优势时,你是绝对正确的,这将是一个意见问题。