Implementing an Oxygene interface with a C# object

Hello,

Let’s consider we have this interface defined in an Oxygene assembly:

  IInputData = interface
    function GetIntProperty: Integer;
    function GetIndexedIntProperty(AIndex: Integer): Integer;

    property IntProperty: Integer read GetIntProperty;
    property IndexedIntProperty[AColIndex: Integer]: Integer read GetIndexedIntProperty;
  end;

This is a pretty basic interface declaration that works well in the “Oxygene” world.
Now, because this is placed inside an assembly, it is available to my fellow developers that use C# inside VisualStudio.
And when they want to implement that interface by a C# object, they have to implement it like this:

    class InputData: InputData
    {
        public InputData()
        {
        }

        #region IInputData
        public int IntProperty { get { return GetIntProperty(); } }
        public int GetIntProperty() { return 0; }

        public int GetIndexedIntProperty(int AIndex) { return 0; }
        public int get_IndexedIntProperty(int AIndex) { return GetIndexedIntProperty(AColIndex); }
        #endregion
    }

This is pretty disturbing to them (and to me) because, basically, every property gets duplicated, but with two different possibilities, depending on the use of a parameter to the property or not.
I’m not sure this behavior can be changed, nor if it should be, I’m mostly curious as to the reasoning that led to this situation.

Regards
Olivier

You dont want the name of the read method in the interface

IInputData = interface

property IntProperty: Integer read;
property IndexedIntProperty[AColIndex: Integer]: Integer;

end;

Should be ok

Cheers,
John

That’s what I thought.

In the Oxygene interface example there are 2 functions and 2 properties declared, so they have to implement 2 functions and 2 properties in C#, as you can see in then C# code.

Everything you declare in the interface has to be implemented.

Well yes, but this code comes from a code base shared with Delphi. And with Delphi, it is mandatory that the getters/setters are declared in the interface itself. And the implementor only has to declare the getters/setters functions; not the properties.

But what’s more puzzling is that IndexedIntProperty does not need to be implemented as a property like IntProperty must be.

That’s because your interface definition is “wrong”. Unlike in Delphi, properties are first-class type member in interfaces, with their implementation (getter/setter) being an implementation detail. Your interface should declare only the properties, not the methods that will implement them:

 IInputData = interface
    property IntProperty: Integer read;
    property IndexedIntProperty[AColIndex: Integer]: Integer read;
  end;

What your declaration did was essentially a combination of three things, one of them a rather new (and cool, albeit not meant for this use) Oxygene feature:

(1) it declared two methods
(2) it declared two properties, entirely unrelated to those three methods
(3) it provided a default implementation (which is an Elements feature, so Visual C# won’t know about that) for the properties, that read them by calling the provided methods.

:slight_smile:


(as an unrelated aside, C# does not support named indexer properties — that’s a language limitation, and quite sad, yes — so those will continue to be awkward for your C# consumers).

1 Like