2012-05-23 12 views
8

En su libro, Jon Skeet se refiere a 7 restricciones sobre tipeo implícito. Necesito aclaración sobre los dos últimos:Restricciones sobre el tipado implícito

A. El tipo que desea que la variable tenga es el tipo de tiempo de compilación de la expresión de inicialización.
B. La expresión de inicialización no implica la variable que se declara.

El libro cubre el material en el mismo orden en que fue lanzado (C# 2 antes de C# 3). En este punto C# 4 no se ha introducido, por lo que asumo que A no se refiere a dynamic. Entonces, ¿cuándo sería el tipo de tiempo de compilación diferente del tipo de tiempo de ejecución de la expresión de inicialización?

Como para B, ¿cuándo puede una expresión de inicialización implicar la variable que se declara?

+0

¿No es 'var x = 2 * x' un buen ejemplo para ** B **? –

+0

@WiktorZychla - eso no compilaría con tipeo explícito tampoco. –

+0

Un ejemplo para A: 'var x = (object) string.Empty;' – phoog

Respuesta

3

En cuanto a B, Henk dio una respuesta perfecta (edit: ahora se elimina), aunque me parece curioso que int x = x = 1; compile. (Yo he pensado x no se considera declarada hasta después de la inicialización Oh, bueno.). Su respuesta fue:

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

En cuanto Un y su pregunta en cuanto a cuando la compilación de tipo wouldn tiempo 't coincide con el tipo de tiempo de ejecución, he aquí un ejemplo en el que diferirían:

var foo = fooFactory.GetFoo(); 

... y que el método de fooFactory se implementa como ....

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

Aquí, foo 's tipo es FooBase (que puede ser una interfaz, clase abstracta o tipo de hormigón sin sellar), y (sin casting) sólo sus características están disponibles. Claramente, FooSubtype implementa o hereda de FooBase.

El tipo que foo contiene en tiempo de ejecución se puede distinguir aquí solo porque muestro la implementación de GetFoo(), pero no es inspeccionado por el compilador. De hecho, la implementación puede que ni siquiera esté disponible (podría estar en otro ensamblado) o puede variar (podría ser virtual). Para determinar el tipo de GetFoo() en tiempo de compilación, y por lo tanto de foo, solo la declaración del método es relevante.

+0

Tiene mi voto para una explicación muy clara, pero en este caso la declaración explícita también debe ser 'FooBase a' y no' FooSubtype a', por lo que no le da ninguna ventaja el uso de la declaración explícita. Creo que la restricción se refiere a cuándo se prefiere la declaración explícita. –

+0

Gracias por su voto, @AlejandroPiad! Pero creo que las "restricciones" se refieren a cuando la declaración implícita es ** posible **. Es decir, si su expresión de inicialización infringe uno de ellos, entonces no puede usar declaración implícita. Si se prefiere es otro asunto con opiniones diferentes. –

+0

Bastante justo. Preferido es la palabra incorrecta. Intenté decir algo así como cuando la tipificación implícita te da una ventaja, pero oye, tienes toda la razón, esa sería una pregunta de opinión. –

2

Mis pensamientos para Un:

No es que el tiempo de compilación es diferente del tipo de ejecución, ya que incluso si el tipo de ejecución no es el mismo que el tipo de compilación (como en cualquier método cuyo retorno tipo es un tipo abstracto), no se puede declarar la variable con el tipo de ejecución de todos modos con tipado explícito.

Pero es posible que desee declarar la variable con un tipo estático más abstracto, incluso si el tipo real dinámico se puede definir en tiempo de compilación. Considere por ejemplo:

ISomething a = new MyOwnSomething(); 

¿Por qué le gustaría hacer esto? Si su MyNewSomething implementa ISomething explícitamente, entonces tendría que hacer un molde para usarlo como un ISomething si se declara en una var. Aquí todavía se ha hecho el reparto, pero que no se ve el poco agraciado:

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

Un ejemplo más artificial es que el código de inicialización puede cambiar más adelante, pero y quiere asegurarse de que a partir de ahora solo usa a como ISomething, y nunca ve los detalles del tipo MyOwnSomething u otras interfaces que pueda estar implementando, de modo que los cambios en el tipo de inicialización no rompan el código.

+1

Otro ejemplo sería una variable que se inicializa a un tipo específico, pero puede tener otros tipos menos específicos en su tiempo de vida. – supercat

+1

Siempre se puede decir 'var a = (ISomething) new MyOwnSomething();' – phoog

+0

@phoog: Exactamente. Eso es lo que la declaración explícita resuelve para ti con una sintaxis más agradable. –

Cuestiones relacionadas