C# 隐式类型的限制
在他的书中,Jon Skeet提到了隐式打字的7个限制。我需要澄清最后两个问题: A.希望变量具有的类型是初始化表达式的编译时类型。C# 隐式类型的限制,c#,types,C#,Types,在他的书中,Jon Skeet提到了隐式打字的7个限制。我需要澄清最后两个问题: A.希望变量具有的类型是初始化表达式的编译时类型。 B.初始化表达式不涉及所声明的变量 这本书以与发行相同的顺序(C#3之前的C#2)覆盖材料。此时还没有引入C#4,因此我假设A不是指动态。那么,编译时类型何时与初始化表达式的执行时类型不同 至于B,什么时候初始化表达式可以包含所声明的变量?我对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!但我认为“限制”指的是何时可以隐式声明。也就是说,如果您的初始化表达式违反了其中之一,那么您就不能使用隐式声明。是否被优先考虑是另一个有不同意见的问题。这很公平。这个词用错了。我想说的是,当隐式打字给你带来优势时,你是绝对正确的,这将是一个意见问题。