Skip to content

Duplicate EventArgs Classes

Jonathan Pobst edited this page Mar 29, 2021 · 3 revisions

When the bindings process sees something in the Java API that looks like an "event", it creates a C# event and a related EventArgs class so that it feels more familiar for .NET users.

For example:

public interface MyInterface
{
    void OnError (int errorCode);
}

Generates:

public interface IMyInterface
{
    // Metadata.xml XPath method reference: path="/api/package[@name='my.package']/interface[@name='MyInterface']/method[@name='onError']"
    [Register ("onError", "(I)V", "GetOnError_Handler, MyClassLibrary")]
    void OnError (int errorCode);
}

public EventHandler<ErrorEventArgs> OnErrorHandler;

public partial class ErrorEventArgs : global::System.EventArgs
{
    public ErrorEventArgs (int errorCode)
    {
        this.errorCode = ErrorCode;
    }

    int errorCode;

    public int ErrorCode {
        get { return errorCode; }
    }
}

However this can create duplicate EventArgs classes if there are multiple interfaces with the same method name in the same namespace, like this:

public interface MyInterface
{
    void OnError (int errorCode);
}

public interface AnotherInterface
{
    void OnError (int errorCode);
}

In this case, the default generated name of ErrorEventArgs creates duplicate classes, resulting in compilation errors like:

Error CS0111: Type 'EventErrorArgs' already defines a member called 'ErrorEventArgs' with the same parameter types
Error CS0102: The type 'EventErrorArgs' already contains a definition for 'errorCode'

In order to fix this, we can use metadata to specify what we want the EventArgs class to be named, so we can choose names that will not conflict. This is accomplished with the argsType attribute:

<attr path="/api/package[@name='my.package']/interface[@name='MyInterface']/method[@name='onError']" name="argsType">MyInterfaceErrorEventArgs</attr>
<attr path="/api/package[@name='my.package']/interface[@name='AnotherInterface']/method[@name='onError']" name="argsType">AnotherInterfaceErrorEventArgs</attr>

Now MyInterface.OnError will generate a MyInterfaceErrorEventArgs class and AnotherInterface.OnError will generate an AnotherInterfaceErrorEventArgs class, and there will no longer be duplicate EventArgs classes.