dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.03k stars 4.03k forks source link

extern event with add/remove doesn't work. #11967

Open yizhang82 opened 8 years ago

yizhang82 commented 8 years ago

Version Used: Visual Studio 2015 Update 2 Steps to Reproduce:

  1. Create a new C# console desktop project
  2. Paste the following code:

class Test { public extern event System.EventHandler FontChanged { [MethodImpl(MethodImplOptions.InternalCall)] add; [MethodImpl(MethodImplOptions.InternalCall)] remove; } }

Similar code with properties works fine.

This is needed to be able to write interop functions (extern + internalcall) that is implemented by runtime / MCG in C#. Today if you disassemble TlbImp generated IL into C# using ILSpy, you'll observe this exact same problem, which is how I discovered this in the first place.

Expected Behavior:

Roslyn emits extern methods for both add/remove with RVA=0 and InternalCall flags.

This is what I get with properties: public extern int MyProp { [MethodImpl(MethodImplOptions.InternalCall)] get; [MethodImpl(MethodImplOptions.InternalCall)] set; }

Metadata from ILDASM:

TypDefName: ConsoleApplication23.Test  (02000003)
Flags     : [NotPublic] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit]  (00100000)
Extends   : 01000010 [TypeRef] System.Object
Method #1 (06000003) 
-------------------------------------------------------
    MethodName: get_MyProp (06000003)
    Flags     : [Public] [HideBySig] [ReuseSlot] [SpecialName]  (00000886)
    RVA       : 0x00000000
    ImplFlags : [IL] [Managed] [InternalCall]  (00001000)
    CallCnvntn: [DEFAULT]
    hasThis 
    ReturnType: I4
    No arguments.

Method #2 (06000004) 
-------------------------------------------------------
    MethodName: set_MyProp (06000004)
    Flags     : [Public] [HideBySig] [ReuseSlot] [SpecialName]  (00000886)
    RVA       : 0x00000000
    ImplFlags : [IL] [Managed] [InternalCall]  (00001000)
    CallCnvntn: [DEFAULT]
    hasThis 
    ReturnType: Void
    1 Arguments
        Argument #1:  I4
    1 Parameters
        (1) ParamToken : (08000002) Name : value flags: [none] (00000000)

Actual Behavior:

CS0073: An add or remove accessor must have a body

AaronRobinsonMSFT commented 3 years ago

@jaredpar This has come up again in relation to some interop scenarios involving porting TlbImp generated code to .NET Core. Not the most pressing but would be interesting given some of our partners.

jaredpar commented 3 years ago

@AaronRobinsonMSFT okay, will add it to the C# 10 backlog and see if we can get it in.