Core: C# 9.0 Overridden virtual function cannot return a covariant derived type that contains the overridden function

Created on 8 Oct 2020  路  4Comments  路  Source: dotnet/core

C# 9.0 Covariant return types - Overridden virtual function - TypeLoadException

Description

C# 9.0 Overridden virtual function works fine when the return type is a covariant derived type, however it fails when the return type is a covariant derived type that contains the overridden function.

Code Snippet

`using System;

class A
{
public virtual A VirtualMethodA() => new();
}

class B : A
{
// C# 9.0 Covariant return types
/*
C# 9.0 Overridden virtual function can return a type derived from the return type declared in the base class method
*/
// Fails:
public override B VirtualMethodA() => new();
// Works:
// public override C VirtualMethodA() => new();
}

class C : A { }

class Program
{
static void Main()
{
B b = new();
b.VirtualMethodA();
Console.WriteLine("Hello, World!");
}
}`

Error

$ dotnet --version
5.0.100-rc.1.20452.10

$ dotnet run
Unhandled exception. System.TypeLoadException: Could not load type 'B' from assembly 'Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
at Program.Main()


Test.exe - Application Error

The exception unknown software exception (0xe0434352) occurred in the application at location 0x00007FFE88BC3B29.

OK Cancel

All 4 comments

I think you ran into this bug: https://github.com/dotnet/runtime/issues/41571. It looks like a PR was merged to fix this in 5.0 rc2.

C# 9.0 Overridden virtual function works fine when the return type is a covariant derived type that contains the overridden function in dotnet version 5.0.100-rc.2.20479.15.

`using System;

class A
{
public virtual A VirtualMethodA() => new();
}

class B : A
{
// C# 9.0 Covariant return types
/*
C# 9.0 Overridden virtual function can return a type derived from the return type declared in the base class method
*/
public override B VirtualMethodA() => new();
// public override C VirtualMethodA() => new();
}

class C : B { }

class Program
{
static void Main()
{
B b = new();
b.VirtualMethodA();
Console.WriteLine("Hello, World!");
}
}`

// Console
/*
$ dotnet --version
5.0.100-rc.2.20479.15

$ dotnet run
Hello, World!
*/

Hi. I still can reproduce TypeLoadException with generics:

using System;

var c = new AChild();

Console.WriteLine("Hello World!");

public abstract class A<T>
{
    public abstract B<T> GetB();
}

public class AChild : A<string>
{
    public override BChild GetB() => null;
}

public class B<T>
{
}

public class BChild : B<string>
{
}

Error:

$ dotnet run
Unhandled exception. System.TypeLoadException: Return type in method 'AChild.GetB()' on type 'AChild' from assembly 'N5, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not compatible with base type method 'A`1[System.__Canon].GetB()'.

$ dotnet --version
5.0.100-rc.2.20479.15

And reproduced in v5.0.0 release (With generics)

$ dotnet run
Unhandled exception. System.TypeLoadException: Return type in method 'AChild.GetB()' on type 'AChild' from assembly 'N5, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not compatible with base type method 'A`1[System.__Canon].GetB()'.
$ dotnet --version
5.0.100
Was this page helpful?
0 / 5 - 0 ratings