Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

416
Visualizações
En C#, ¿por qué no puedo completar una variable local usando su dirección y luego usar la variable más tarde?

Considere el siguiente código:

 private unsafe void Function() { int length; // This line raises error CS1686, "Local 'length' or its members cannot have their address taken and be used inside an anonymous method or lambda expression". glGetProgramiv(1, GL_PROGRAM_BINARY_LENGTH, &length); FunctionWithLambda(() => Console.WriteLine(length)); } private void FunctionWithLambda(Action callback) { callback(); }

Tenga en cuenta que estoy tomando la dirección de length (una variable local), luego uso la variable en sí ( no su dirección) en una lambda. Entiendo por qué una dirección de variable local no se puede usar en una lambda directamente (consulte ¿Por qué no puedo pasar la dirección de una variable a una función anónima? , entre otros ejemplos), pero ¿por qué no puedo usar el valor de length una vez? asignado (incluso si esa asignación usa el operador & )? La documentación oficial del error CS1686 (https://docs.microsoft.com/bs-latn-ba/dotnet/csharp/misc/cs1686 ) no ha aclarado esta confusión.

Mi suposición es que esto es simplemente una limitación de idioma, pero tengo curiosidad por saber si hay una razón técnica subyacente por la que me estoy perdiendo. También tenga en cuenta que no estoy preguntando cómo solucionar este problema (sé que primero puedo copiar fácilmente la length a otra variable local).

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

La especificación de C# dice lo siguiente (en negrita) :

23.4 Variables fijas y móviles

El operador de dirección (§23.6.5) y la declaración fixed (§23.7) dividen las variables en dos categorías:
Variables fijas y variables móviles .

...recorte...

El operador & (§23.6.5) permite obtener la dirección de una variable fija sin restricciones. Sin embargo, debido a que una variable móvil está sujeta a reubicación o eliminación por parte del recolector de basura, la dirección de una variable móvil solo se puede obtener utilizando una declaración fixed (§23.7), y esa dirección sigue siendo válida solo durante la duración de esa declaración fixed .

En términos precisos, una variable fija es una de las siguientes:

  • Una variable que resulta de un nombre simple (§12.7.3) que hace referencia a una variable local, un parámetro de valor o una matriz de parámetros, a menos que la variable sea capturada por una función anónima (§12.16.6.2).
  • .....

Por lo tanto, está explícitamente prohibido por la especificación. En cuanto a por qué está prohibido, tendrías que preguntarle a los diseñadores del lenguaje, pero teniendo en cuenta la complejidad involucrada en la captura de variables, es algo lógico.

over 4 years ago · Santiago Trujillo Relatório

0

Supongo que la razón es simple: Demasiado complejo para compilar .

Hay 2 problemas que el compilador tiene que resolver:

  1. Genere un curso para el método anónimo.
  2. Sincroniza el valor de la variable.

Supongamos que los siguientes códigos son válidos.

 unsafe void Function() { int length = 1; void bar() => Console.WriteLine(length); bar(); foo(&length); bar(); } unsafe void foo(int* i) { (*i)++; }

El resultado esperado es:

 1 2

Para resolver el primer problema, C# generará una clase anónima para mantener el valor superior.

Aquí está el pseudocódigo:

 class _Anonymous { public int _length; public void _bar() { Console.WriteLine(_length); } } unsafe void Function() { int length = 1; var a = new _Anonymous { _length = length }; a._bar(); foo(&length); a._bar(); }

Para resolver el segundo problema, C# usa el campo generado en lugar de la variable local original.

 unsafe void Function() { //int length = 1; var a = new _Anonymous { _length = 1 }; a._bar(); foo(&a._length); a._bar(); }

Estos son todos los trabajos que puede hacer un compilador. Pero hasta ahora los códigos siguen sin funcionar, necesitamos un bloque fijo adicional.

 unsafe void Function() { var a = new _Anonymous { _length = 1 }; a._bar(); fixed (int* p = &a._length) foo(p); a._bar(); }

Entonces, la limitación se puede eliminar con un compilador más inteligente, pero las cosas se vuelven más fáciles si prohibimos este tipo de códigos.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda