¿Cómo puedo determinar si un método necesita ser llamado con "Llamar" o "Llamar"?.NET CIL ¿Llamada o CallVirt?
Respuesta
Puede seguir estas simples reglas, uno por uno para determinar qué se debe utilizar:
- es el método
static
? Luego usecall
. - ¿Es el tipo que invoca en un tipo de valor? Luego use
call
. (Esto no aplicar si se encajona el valor - a continuación, en realidad se está invocando enobject
o alguna de las interfaces, y esos son los tipos de referencia.) - es el método que está invocando declarado
virtual
oabstract
? Luego usecallvirt
. - ¿Está invocando el método a través de una referencia de interfaz? Luego use
callvirt
. - ¿El método que invoca está declarado
override
, pero ni el método ni el tipo de declaración declararonsealed
? Luego usecallvirt
.
En todos los demás casos, no se requiere un despacho virtual para que puede utilizar call
- pero usted debe uso callvirt
. He aquí por qué:
El uso de callvirt
en métodos no virtuales es equivalente a call
excepto cuando el primer argumento es nulo. En ese caso, callvirt
lanzará un NullReferenceException
inmediatamente, mientras que call
no lo hará. Esto tiene sentido, porque callvirt
está destinado a ser utilizado en casos en que se desea el despacho de métodos virtuales, y no se puede realizar el envío de métodos virtuales si no se tiene un objeto para realizar una búsqueda de tablas virtuales.
Tenga en cuenta que callvirt
aún arrojará una excepción si el primer argumento es nulo, incluso si no es necesaria una búsqueda vtable!
Teniendo en cuenta esta información, utilizando callvirt
para todas las invocaciones de métodos no estáticos sobre los tipos de referencia (como el compilador de C# hace) puede ser preferible, ya que causará un NullReferenceException
de inmediato en el lugar de llamada en lugar de en algún momento más tarde, cuando this
se acostumbra (explícita o implícitamente) dentro del método.
Pero .NET usa "llamada" cuando llama algo así como Point.X. De lo que estoy leyendo aparentemente los métodos de tipo de valor usan "llamar". – Will
Sí, porque esos métodos no son virtuales, por lo que esperaría que el resultado utilizara "llamada". Lee mi respuesta nuevamente (Además, las estructuras * no pueden * tener miembros virtuales ya que no se pueden heredar.) – cdhowie
Eso tiene sentido, gracias. Es extraño que la reflexión muestre que "IsVirtual" es cierto para los métodos struct. – Will
De forma predeterminada, el compilador de C# siempre usa callvirt para todo excepto para las llamadas estáticas o de tipo de valor. Esto provoca una comprobación nula implícita del argumento 'this' (arg0). No se requiere estrictamente que sigas esta convención, pero cualquier método virtual en un tipo de referencia definitivamente requerirá callvirt.
Excepto por métodos virtuales en clases selladas. –
Si utiliza invocar un método dinámico en un método virtual, el tiempo de ejecución arroja una excepción de seguridad.
- 1. Call and Callvirt
- 2. Ventajas del conocimiento de CIL en .NET
- 3. CIL, CLS y CTS en .NET
- 4. Desarmar programáticamente CIL
- 5. Learning CIL
- 6. ¿Ha cambiado CIL (Common Intermediate Language) para .Net 4.0?
- 7. ¿Por qué el compilador C# emite una instrucción callvirt para una llamada al método GetType()?
- 8. ¿Visualizarán VB.NET y C# CIL lo mismo?
- 9. Stringbuilder en CIL (MSIL)
- 10. CIL stack exchange instruction
- 11. Buscando una forma de manipular .Net CIL en tiempo de ejecución
- 12. Comportamiento de delegado CIL con "estática" conflictiva del método de destino
- 13. Cómo insertar el código CIL en C#
- 14. ¿Cuáles son los mejores recursos para aprender CIL (MSIL)
- 15. .NET 2.0 o 3.5?
- 16. .NET AJAX ¿Llamadas a ASMX o ASPX o ASHX?
- 17. ¿Utiliza attach() o variables de llamada por nombre o división?
- 18. ¿Escribiendo un compilador para .net - IL o Bytecode?
- 19. ¿Compilación o complicación del código .NET?
- 20. ¿Patrón de observador o devolución de llamada?
- 21. DropDownListPara devolución de llamada o declaración if
- 22. ¿Cuál es la diferencia entre CIL y MSIL (IL)?
- 23. ¿Cómo traducir "por defecto (SomeType)" de C# a CIL?
- 24. Restablecer o borrar .NET MemoryStream
- 25. CGAL for .Net (o C#)
- 26. .NET EventHandlers - ¿Genérico o no?
- 27. .Net AssemblyName.version Construir o Revisión
- 28. ¿Puedo crear una expresión optimizada recursiva llamada de cola?
- 29. llamada ambigua con una lambda en C# .NET
- 30. Realizar una llamada a una biblioteca .NET 4 desde 3.5
¿Qué tiene esto que ver con C#? – SLaks