Por mi comprensión del alcance, el primer ejemplo debe estar bien.
Su comprensión del alcance está bien. Esto no es un error de alcance. Es un uso inconsistente del error de nombre simple.
int i = 10; // error, 'i' ya existe
Ese no es el error que se informó. El error que se informó es "una variable local llamada i no puede ser declarada en este ámbito porque daría un significado diferente a lo que ya se utiliza en un ámbito secundario para denotar algo más"
El mensaje de error es diciéndole cuál es el error; leer el mensaje de error nuevamente No dice en ninguna parte que haya un conflicto entre las declaraciones; dice que el error es porque eso cambia el significado del nombre simple. El error es no la redeclaración; es perfectamente legal tener dos cosas en dos ámbitos diferentes que tengan el mismo nombre, incluso si esos ámbitos anidan. Lo que es no legal es tener un nombre simple significa dos cosas diferentes en declaraciones de variables locales anidadas espacios.
Se podría obtener el error "una variable local llamada i ya se ha definido en este ámbito" si en vez has hecho algo así como
int i = 10;
int i = 10;
Seguramente 'i' es ya sea en su alcance o no.
Seguro, pero ¿y qué? Si un i dado está en el alcance o no es irrelevante. Por ejemplo:
class C
{
int i;
void M()
{
string i;
Perfectamente legal. El exterior i está en el alcance a lo largo de M. No hay ningún problema en absoluto al declarar un i local que sombrea el alcance externo. Lo que sería un problema es si usted dice
class C
{
int i;
void M()
{
int x = i;
foreach(char i in ...
Porque ahora que usted ha utilizado i para significar dos cosas diferentes en dos espacios de declaración de variables locales anidados - una variable de bucle y un campo. Eso es confuso y propenso a errores, por lo que lo hacemos ilegal.
¿Hay algo no obvio en el alcance que no entiendo, lo que significa que el compilador realmente no puede resolver esto?
No entiendo la pregunta. Obviamente, el compilador es capaz de analizar completamente el programa; si el compilador no pudo resolver el significado de cada uso de i, ¿cómo podría informar el mensaje de error? El compilador puede determinar completamente que ha usado 'i' para significar dos cosas diferentes en el mismo espacio de declaración de variable local, e informa el error en consecuencia.
Es como la ley del cinturón de seguridad. No hay ninguna razón técnica por la que no pueda conducir un automóvil sin una, pero es un buen trabajo que la ley exista para detenerlo, ya que puede salvarlo de algunas colisiones muy desagradables. –