In C#, is it possible to implement an interface member using a member with a different name, like you can do in VB.NET?
Asked Answered
Y

2

13

Ok, this is a question I'm asking, not as in demonstrating good coding practices (this actually could be considered a bad practice) but rather in regards to 'can' it be done at all.

That said, in VB.NET you implement an interface like this...

Sub SomeInterfaceMember()
    Implements ISomeInterface.SomeInterfaceMember
End Sub

while in C# you do it explicitly like this (which can only be called via the interface)...

void ISomeInterface.SomeInterfaceMember(){}

or more simply, implicitly like this (in which case you can call it directly, or via the interface)...

void SomeInterfaceMember(){} // <-- This name matches the interface member

However, regarding VB, you can also do this, using any name you want for the member...

Sub SomeRandomMemberName() // <-- This name doesn't match the interface member
    Implements ISomeInterface.SomeInterfaceMember
End Sub

In other words, the method that handles the implementation can have a completely different name than the interface's member name.

I'm just wondering if there's something similar to this in C#. (Yes, I know I can simply do an explicit interface, then access it via another 'wrapper' member with a different name that simply delegates to it, but in VB.NET, you do both with a single method.)

So can that be done?

Mark

Yearling answered 4/4, 2011 at 1:7 Comment(8)
This is sometimes a good practise. E.g. if you are implementing IDisposable and you wish to have a Close method, you can roll them into one with Sub Close Implements IDisposable.Dispose. Brief, readable.Wasp
Mark, I ironically just typed the same thing below!Yearling
@MarkJ: I dislike the practice you describe, since it leaves unclear the question of whether one should endeavor to call Close as well as Dispose. IMHO, if a member is public, it should have the same name as its interface method. On the other hand, if two interface members which have the same name should have distinct protected virtual implementations, the only way to achieve that in C# would be to have sealed explicit implementations call virtual implementations, adding an extraneous level of indirection.Klatt
@Supercat, the problem I have with your statement is that sometimes you can't have the same name publicly as the interface. Interface definitions only apply when you are calling something via that interface. And what if you implement two different interfaces which share a name but mean different things in context? The current work-around is to create a wrapper that calls the member via the interface, but the nice thing about in VB was you didn't have to. Actually, to drive the point home even more, if your statement is true, why allow explicit interface definitions at all?Yearling
@MarqueIV: Having IWoozle.Foo() implemented by a public method WoozleClass.Bar() seems like a code smell. I would see nothing wrong, however, with having an IWoozle.Foo() implemented by a *protected* method IWoozleFoo()` if the name Foo was otherwise taken. To my mind, having a public method Close implement IDisposable.Dispose() makes a promise that the two functions will always behave absolutely identically; in practice one may often want to allow for divergent semantics (e.g. allow a re-open following a Close but not Dispose, etc.).Klatt
@MarqueIV: I guess I can imagine cases where it might make sense for a class which implements two interfaces to have public names which make abundantly clear that they are implementations of particular interface methods (similar to the protected method above) but more often I've seen suggestions like the Dispose/Close ones, which I don't like as advice.Klatt
@Supercat, you just proved my point. In your example you stated 'having a public method Close implement IDisposable.Dispose() makes a promise that the two functions will always behave absolutely identically.' Exactly. That is what we want and is precisely the point. If we were to want what you describe in the other part of that statement... 'one may often want to allow for divergent semantics' then you wouldn't use this method. You couldn't actually as you'd need two separate implementations. Again, you're arguing an invalid point to the question.Yearling
Looked at another way, what if the interface was hidden to the consumer, and/or what if the interface members were named accordingly? 'MyHiddenSave' and 'MyHiddenReload'? However in this particular class, we do want to expose the Save and Reload functionality to the consumer since it is allowed. We'd just like to point Save->MyHiddenSave and Reload->MyHiddenReload. Yes, names like this are ridiculous, but sometimes you're forced to work with other/existing interfaces. This doesn't mean you need to propagate their mess to your consumers. You're in a sense, just creating an alias.Yearling
O
7

No, this isn't possible in C#. (You can't "explicitly implement an interface" in VB.NET either.)

Oxtail answered 4/4, 2011 at 1:8 Comment(11)
I had a feeling you couldn't. BTW, I'm also up-voting you for the extra info you provided. Thanks! :)Yearling
I think we can all agree that C# not allowing this is a bloody good thingDeprive
@MattDavey: I don't feel strongly about it either way... why is it a "bloody good thing"?Oxtail
@MattDavey, I personally don't think it's a 'good thing' myself. We have a base class called DesignerContext which we subclass for various parts of the program. However, our app's framework injects it in via an IDesignerContextAware interface. I personally find it very annoying that I can't just attach the interface to ProgramContext (which is of type DesignerContext) as it makes things more readable. Our only solution now requires two implementations... the one called implements IDesignerContextAware, and a second called ProgramContext that just delegates down.Yearling
Think about what the point of an interface is - it's describing the API that an object exposes, what methods and properties it has available to use. What use is an interface if any old object can come along and change that contract?Deprive
@MattDavey: I don't see how it's changing the contract... all it's changing is the name of the method, which is irrelevant to the interface (arguments/return value) of the method and its supposed behavior.Oxtail
The interface of a method is more than just its signature - otherwise your contract might as well just say "this object has a function that eats an int and spits out a string", which is not terribly useful.Deprive
Nah, it's just the signature. :P The name used in the implementation is pretty irrelevant.Oxtail
OK, rename all the properties/methods on all of your interfaces to nonsensical random letters and numbers - then come back and say that again ;)Deprive
@MattDavey, you're missing the point, and @Mehrdad, you're not explaining it properly. The name of the interface's member DOES NOT CHANGE when called VIA THE INTERFACE regardless of what the method is called on the class that implements the interface. If I have an object Foo that implements ILaa, and Foo has FooMethod which implements ILaa.LaaMethod, I can call that method either by Foo.FooMethod, or I can cast Foo to ILaa, then call LaaMethod. I haven't changed anything or broken any contract. 'Close implements IDisposable.Dispose' is a great example of how this is helpful.Yearling
@MattDavey: The line void myInterface.foo() is equivalent to Private Sub SomeRandomJunkA28GWE02() Implements myInterface.foo. The names myInterface and foo are important, but the name SomeRandomJunkA28GWE02 is basically irrelevant outside some Reflection scenarios.Klatt
G
1

It "can" be done in the sense that you can achieve a result that's basically indistinguishable from the VB scenario by using explicit implementation + a public method that calls that implementation.

Aside from cases involving reflection, this really will end up being the same thing.

Gallia answered 4/4, 2011 at 3:50 Comment(3)
Yes, I know that as I said exactly that in the question itself. But that wasn't what I was asking. I wanted to know if, like in VB.NET, you could do so with a single statement in C#, which it doesn't look like you can do.Yearling
@MarqueIV so is it confirmed?, you can not in c#?, seems odd. yes i agree its probably a good thing just interesting.Ethel
Confirmed? WellI haven’t found a single reference anywhere showing how to do that. Is that definitive? If this were Vegas I know where I’d put my money! :)Yearling

© 2022 - 2024 — McMap. All rights reserved.