Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Generic Type allows you to create types with abstract classes when the constrant should block it #101962

Open
Faolan-Rad opened this issue May 7, 2024 · 5 comments
Labels
area-TypeSystem-coreclr in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@Faolan-Rad
Copy link
Contributor

Description

You can create types with new() constraint which should block the use of abstract classes but it allows them any way though the use of the MakeGenericType and then you can instantiate them through activator

Reproduction Steps

public abstract class W { 
    /// This makes the bug happen
    public W()
    { }
}

public sealed class Trains<T> where T : W, new() { }

internal class Program
{
    static void Main(string[] args)
    { 
        //var e = new Trains<W>(); // This line has expected must be a none-abstract type 
        var e = Activator.CreateInstance(typeof(Trains<>)
            .MakeGenericType(typeof(W))); // This runs add creates the invalid type anyway
        Console.WriteLine(e?.ToString());
    }
}

Expected behavior

Probably for MakeGenericType to throw an invalid type exception

Actual behavior

It lets the type get created and it can be instated with the activator without a problem

Regression?

It happens from 6 - 8 did not test any more

Known Workarounds

You could add your own type check before hand

Configuration

.net 6 - 8

Other information

MakeGenericType probably just add a is abstract check for when it is a new() constraint

@Faolan-Rad
Copy link
Contributor Author

I did a test it also happens with method reflection

using System.Reflection;

public abstract class W {
    /// This makes the bug happen
    public W()
    { }
}

public sealed class Trains<T> where T : W, new() { }

internal class Program
{

    public static T Create<T>() where T : W , new()
    {
        return new T();
    }

    static void Main(string[] args)
    {
        var shouldNotGive = typeof(Program).GetMethod("Create", BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(typeof(W));
        shouldNotGive.Invoke(null, Array.Empty<object>());// Will Try and run the method and get a MissingMethodException: Cannot dynamically create an instance of type 'W'. Reason: Cannot create an abstract class.
        //var e = new Trains<W>(); // This line has expected must be a none-abstract type 
        var e = Activator.CreateInstance(typeof(Trains<>)
            .MakeGenericType(typeof(W))); // This runs add creates the invalid type anyway
        Console.WriteLine(e?.ToString());
    }
}

@steveisok
Copy link
Member

/cc @fanyang-mono

Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-reflection
See info in area-owners.md if you want to be subscribed.

@jkotas
Copy link
Member

jkotas commented Jun 14, 2024

This is type loader problem. The repro happens to use reflection, but it would repro with plain IL too.

#101963 has a proposed fix.

@steveisok steveisok removed the untriaged New issue has not been triaged by the area owner label Jun 21, 2024
@steveisok steveisok added this to the 9.0.0 milestone Jun 21, 2024
@ivdiazsa ivdiazsa self-assigned this Aug 1, 2024
@dotnet-policy-service dotnet-policy-service bot added the in-pr There is an active PR which will close this issue when it is merged label Aug 2, 2024
@ivdiazsa ivdiazsa removed their assignment Aug 2, 2024
@steveisok
Copy link
Member

Since #101963 is a breaking change, we'll apply it to .NET 10.

@steveisok steveisok modified the milestones: 9.0.0, 10.0.0 Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-TypeSystem-coreclr in-pr There is an active PR which will close this issue when it is merged
Projects
None yet
Development

No branches or pull requests

4 participants