¿Por qué el compilador de C # permite que esto se compile y genera una excepción de tiempo de ejecución cuando se ejecuta?
class Program
{
static void Main(string[] args)
{
IEnumerable<Test> list = new List<Test>() { new Test() };
foreach(IDisposable item in list)
{
}
}
}
public class Test
{
}
Esto compila con cualquier interfaz y no compila si reemplaza IDisposable con clase concreta.
c#
covariance
ekalchev
fuente
fuente
Test
los cuales no aplicarIDisposable
. Efectivamente, el foreach intenta lanzar cada elemento a la interfaz y lanza una excepción si esto falla. Lo mismo que si escribieras(IDisposable)currentElement
. Sin embargo, no puedo ver por qué no debería compilarse en la clase concreta.foreach (IDisposable item in list.OfType<IDisposable>())
pero supongo que no es el puntoRespuestas:
El
foreach
bucle tiene un reparto implícito. Es más o menos así:Antes de los genéricos, eso era mucho más práctico que tener que enviar el código fuente. Ahora no es tan importante, pero sería extraño que no se compilara. Tenga en cuenta que el compilador se compruebe que es al menos posible . Si usa
foreach (string item in list)
eso, no se compilaría, porque aTest
no puede ser astring
, pero aTest
puede ser unIDisposable
, porque podría referirse a una instancia de una subclase deTest
esos implementosIDisposable
. Si seTest
sella la clase, no se compilará incluso con ellaIDisposable
, porque entonces unaTest
instancia no se puede implementarIDisposable
.Básicamente, se compilará si se compila una conversión del
Test
tipo de iteración, y de lo contrario no se compilará. Pero fallará en el tiempo de ejecución si un lanzamiento normal también falla en el tiempo de ejecución.fuente