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

Relax CS0030 to not error on conversion of IDynamicInterfaceCastable #3575

Open
elinor-fung opened this issue Jun 16, 2020 · 5 comments
Open

Comments

@elinor-fung
Copy link
Member

Version Used:
.NET Core 5.0.100-preview.7.20316.2

Steps to Reproduce:

For .NET 5, the IDynamicInterfaceCastable (dotnet/runtime#36654) was added (dotnet/runtime#37042) to allow participation in a cast at run time where the implementing class is cast to an interface that is not in its class metadata.

As a result, an explicit cast the compiler recognizes as impossible could actually be possible if the object implements IDynamicInterfaceCastable.

interface ITest { void Method(); }

[System.Runtime.InteropServices.DynamicInterfaceCastableImplementationAttribute]
interface ITestImpl : ITest
{
    void ITest.Method() { }
}

sealed class Castable : System.Runtime.InteropServices.IDynamicInterfaceCastable
{
    public RuntimeTypeHandle GetInterfaceImplementation(RuntimeTypeHandle interfaceType)
    {
        return Type.GetTypeFromHandle(interfaceType) == typeof(ITest)
            ? typeof(ITestImpl).TypeHandle
            : default(RuntimeTypeHandle);
    }

    public bool IsInterfaceImplemented(RuntimeTypeHandle interfaceType, bool throwIfNotImplemented)
    {
        return Type.GetTypeFromHandle(interfaceType) == typeof(ITest);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Castable obj = new Castable();
        ITest t = (ITest)obj; // error CS0030: Cannot convert type 'Castable' to 'ITest'
        t.Method();
    }
}

Expected Behavior:
No error if the type implements IDynamicInterfaceCastable.

Actual Behavior:
error CS0030: Cannot convert type 'testApp.Castable' to 'testApp.ITest'

The user needs to first cast to object, then the desired interface:

ITest t = (ITest)(object)obj;

cc @AaronRobinsonMSFT @jkoritzinsky

@CyrusNajmabadi
Copy link
Member

This sounds like a language change request afaict. Would you like me to move this to dotnet/csharplang? I think we'd have to spec this as how the language works in order for the compielr to know that it shoudl allow this sort of thing.

@elinor-fung
Copy link
Member Author

Ah, okay - yes, please do move this where it belongs.

@CyrusNajmabadi CyrusNajmabadi transferred this issue from dotnet/roslyn Jun 16, 2020
@CyrusNajmabadi
Copy link
Member

Done :) Are you the write dotnet/runtime representative to communicate on this with for the LDM?

@YairHalberstadt
Copy link
Contributor

No error if the type implements IDynamicInterfaceCastable

Given that the compiler cannot guarantee this cast is valid, should there be a warning?

@AaronRobinsonMSFT
Copy link
Member

Given that the compiler cannot guarantee this cast is valid, should there be a warning?

I don't think so. The compiler check is merely convenience because it can detect the case with the type data. In this case it is no different than if the object was typed as object. I would instead like to see the compiler treat casts from objects typed as object or implementing IDynamicInterfaceCastable the same - the compiler just can't determine success at compile time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants