Skip to content

CLIEvent not properly exposed in certain cases when there are more than one events in a project (.NET 7 regression?) #14996

@flannelhead

Description

@flannelhead

When exposing events from F# code to C# along these guidelines, in some cases some of the events fail to be exposed properly:

  • When a project contains more than one module that have classes with exposed events
  • When a project contains a module that has two or more classes with exposed events

In these cases, one can't use the += operator on the events to add handlers in C# code. This happens only if the F# project targets net7.0 or newer (checked also with net8.0 preview 2).

Repro steps

Case 1:

Consider a solution with these projects:

  • LibraryWithTwoClassesAndTwoEvents - F# lib project
  • TestApp - C# project that consumes the interface of the lib

The lib project has the following code in a .fs file:

namespace EventTest

open System

module LibraryWithTwoClassesAndTwoEvents =
    let event = new DelegateEvent<EventHandler<EventArgs>>()
    type MyClass() =
        [<CLIEvent>]
        member this.Event = event.Publish

    let event2 = new DelegateEvent<EventHandler<EventArgs>>()
    type MyClass2() =
        [<CLIEvent>]
        member this.Event = event2.Publish

The TestApp has the following code:

using EventTest;

var obj1 = new LibraryWithTwoClassesAndTwoEvents.MyClass();
obj1.Event += MyEventHandler;   // This doesn't work
obj1.add_Event(MyEventHandler); // but this does

void MyEventHandler(object sender, EventArgs e)
{
    throw new NotImplementedException();
}

If one removes the type MyClass2 from the lib, the above code works. It also works when the lib targets .NET 6 or lower.

Case 2:

Consider a solution with these projects:

  • LibraryWithTwoModulesAndTwoEvents - F# lib project
  • TestApp - C# project that consumes the interface of the lib

The lib project has the following code in two files:

Module1.fs:

namespace EventTest

open System

module Module1 =
    let event = new DelegateEvent<EventHandler<EventArgs>>()
    type MyClass() =
        [<CLIEvent>]
        member this.Event = event.Publish

Module2.fs::

namespace EventTest

open System

module Module2 =
    let event = new DelegateEvent<EventHandler<EventArgs>>()
    type MyClass() =
        [<CLIEvent>]
        member this.Event = event.Publish

The TestApp has the following code:

using EventTest;

var obj1 = new Module1.MyClass();
obj1.Event += MyEventHandler;   // This works

var obj2 = new Module2.MyClass();
obj2.Event += MyEventHandler;   // This doesn't work
obj2.add_Event(MyEventHandler); // but this does

void MyEventHandler(object sender, EventArgs e)
{
    throw new NotImplementedException();
}

Reproducer is attached with both of the cases and also an example of a project which has two events in the same class, which builds successfully.
repro.zip

Expected behavior

Events are exposed properly to the interface to be consumed by C#.

Actual behavior

Events are not properly exposed - += and -+ operators can't be used to add/remove event handlers.

Known workarounds

When this issue occurs, using the add_Event and remove_Event methods directly seems to work.

Metadata

Metadata

Assignees

Labels

Area-Compiler-CodeGenIlxGen, ilwrite and things at the backendBugImpact-High(Internal MS Team use only) Describes an issue with extreme impact on existing code.Regression

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions