¿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

Testlos 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
foreachbucle 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 aTestno puede ser astring, pero aTestpuede ser unIDisposable, porque podría referirse a una instancia de una subclase deTestesos implementosIDisposable. Si seTestsella la clase, no se compilará incluso con ellaIDisposable, porque entonces unaTestinstancia no se puede implementarIDisposable.Básicamente, se compilará si se compila una conversión del
Testtipo 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