dotnet / vblang

The home for design of the Visual Basic .NET programming language and runtime library.
289 stars 66 forks source link

Interface Constructor #143

Open vbjay opened 7 years ago

vbjay commented 7 years ago

Not even sure if this is a vb or .net thing. I would like to be able to define a specific exception to no constructors in interfaces. Yes I know we have MustInherit or abstract classes.

Example:

Public Interface IPluginSettingKey
        Property SettingID As Guid
        Property Name As String
        Property PluginID As Guid
        Property WebhookID As Long?

        Sub New(SettingKey as IPluginSettingKey)

    End Interface
rskar-git commented 7 years ago

Behind the scenes, an Interface is pretty much just a table of Delegates. I don't believe there's any executable code packaged within an Interface. Conceptionally (if not really), what instantiates an Interface is some (hidden) factory function inside each Class that implements it. Just saying something like New MyInterface() wouldn't be workable without somehow indicating the intended (underlying) Class that brings the actual executable code.

In classic VB (VB6, VBA), there was this concept of a "Class Module", and that resembled a marriage of a (potentially Public) Interface to a Private (and virtually unnamed or hidden) Class. Its "constructor" would be a factory function that creates an instance of this Private Class. So, in classic VB, New MyClassMod would translate to something like CType(New Class_Of_MyClassMod(), MyClassMod) in today's VB (where MyClassMod is an Interface).

Yours is a common ask - see e.g. https://stackoverflow.com/questions/2804041/constructor-in-an-interface. But "Interface" isn't another name for "Class". It isn't an executable: It's a switchboard into an executable.

vbjay commented 7 years ago

I understand that. What I meant was requiring a contract that an item that implements x interface also implemented a constructor with an argument typed as that interface. I am using mef and working on plugin settings. I defined an interface and even a base class that implements this interface. In the main app I have a class that implements this interface. It is an EF model class. My goal is to be able to translate between the plugin settings and the ef storage. I just think requiring any implementation of my interface to have a constructor could be useful in many areas.

On Wed, Jul 19, 2017, 2:55 PM rskar-git notifications@github.com wrote:

Behind the scenes, an Interface is pretty much just a table of Delegates. I don't believe there's any executable code packaged within an Interface. Conceptionally (if not really), what instantiates an Interface is some (hidden) factory function inside each Class that implements it. Just saying something like New MyInterface() wouldn't be workable without somehow indicating the intended (underlying) Class that brings the actual executable code.

In classic VB (VB6, VBA), there was this concept of a "Class Module", and that resembled a marriage of a (potentially Public) Interface to a Private (and virtually unnamed or hidden) Class. Its "constructor" would be a factory function that creates an instance of this Private Class. So, in classic VB, New MyClassMod would translate to something like CType(New Class_Of_MyClassMod(), MyClassMod) in today's VB (where MyClassMod is an Interface).

Yours is a common ask - see e.g. https://stackoverflow.com/questions/2804041/constructor-in-an-interface. But "Interface" isn't another name for "Class". It isn't an executable: It's a switchboard into an executable.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dotnet/vblang/issues/143#issuecomment-316483024, or mute the thread https://github.com/notifications/unsubscribe-auth/ADdhsYAdNt-44UMYYnTk8ccajJPR96TOks5sPlEogaJpZM4Oc3hq .

vbjay commented 7 years ago

Example:

rskar-git commented 7 years ago

It seems to me that a "work-around" like the one below should meet the need. Could you elaborate on how that might not be enough?

Interface IPluginSettingKey
    ' ...
    Function New_IPluginSettingKey(SettingKey As IPluginSettingKey) As IPluginSettingKey
    ' ...
End Interface

Class PluginSetting
    Implements IPluginSettingKey
    ' ...
    Function New_IPluginSettingKey(SettingKey As IPluginSettingKey) As IPluginSettingKey _
        Implements IPluginSettingKey.New_IPluginSettingKey
        Return CType(New PluginSetting(SettingKey), IPluginSettingKey)
    End Function
    ' ...
End Class

Note that Sub New (in any form) cannot implement Interface members, nor can be made Overridable (or MustOverride), so if that's what you're after, that's probably a huge ask.

vbjay commented 7 years ago

No. Wasn't looking for overridable. Just looking to force a constructor with specific signature. Each implementation must write their own code for it.

I guess I could have a non constructor InitFromInterface type of method.

On Thu, Jul 20, 2017, 11:21 AM rskar-git notifications@github.com wrote:

It seems to me that a "work-around" like the one below should meet the need. Could you elaborate on how that might not be enough?

Interface IPluginSettingKey ' ... Function New_IPluginSettingKey(SettingKey As IPluginSettingKey) As IPluginSettingKey ' ... End Interface

Class PluginSetting Implements IPluginSettingKey ' ... Function NewIPluginSettingKey(SettingKey As IPluginSettingKey) As IPluginSettingKey Implements IPluginSettingKey.New_IPluginSettingKey Return CType(New PluginSetting(SettingKey), IPluginSettingKey) End Function ' ... End Class

Note that Sub New (in any form) cannot implement Interface members, nor can be made Overridable (or MustOverride), so if that's what you're after, that's probably a huge ask.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dotnet/vblang/issues/143#issuecomment-316737661, or mute the thread https://github.com/notifications/unsubscribe-auth/ADdhsXWhyJDHRHuaEkepaAOrBvz00RIBks5sP3B0gaJpZM4Oc3hq .

jrmoreno1 commented 7 years ago

The point is that having a constructor you can't call, doesn't gain you anything. If you're thinking of a builder pattern or Dependency Injection, it doesn't help because you can't enforce that that constructor was what was used.

vbjay commented 7 years ago

I know. I was more looking for a way to allow translation from one implementation to another. One implenentaition was the EF model and how it was stored in the db. One in the plugin library that the plugins used. The idea being that if you have an interface, I think placing a constructor signature of

New (input as TheInterface) should be allowed in the interface. That way all implementers have to write a translation into their type to be used.

I want to be able to pass in an EF model into the constructor of a plugin settings object and the same for an EF model object.

On Sun, Aug 27, 2017, 6:34 PM John Moreno notifications@github.com wrote:

The point is that having a constructor you can't call, doesn't gain you anything. If you're thinking of a builder pattern or Dependency Injection, it doesn't help because you can't enforce that that constructor was what was used.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dotnet/vblang/issues/143#issuecomment-325229276, or mute the thread https://github.com/notifications/unsubscribe-auth/ADdhsZZYbag_8eJFaw6IZZXZxl6X5PFCks5sce7ogaJpZM4Oc3hq .