views:

61

answers:

3

I have a control that overrides the protected GetService method and assigns it to the IServiceProvider interface:

Class MyControl
    Inherits Control
    Implements IServiceProvider

    Protected Overrides Sub GetService(t as Type) as Object Implements IServiceProvider.GetService
    End Sub

End Class

I'm struggling to convert this to c#. I've tried implicit v. explicit but I must be getting the syntax wrong.

+7  A: 

You would do this like:

class MyControl : Control, IServiceProvider
{
     // Explicitly implement this
     object IServiceProvider.GetService(Type t)
     {
          // Call through to the protected version
          return this.GetService(t);
     }

     // Override the protected version...
     protected override object GetService(Type t)
     {
     }
}

That being said, Control already implements IServiceProvider (via Component). You really can just do:

class MyControl : Control
{
     protected override object GetService(Type t)
     {
     }
}
Reed Copsey
Good job, beat me to it +1
Richard J. Ross III
That doesn't work. It says that method cannot implement it because it's not public.
Jules
@Jules: Sorry about that - was too fast, and forgot about one of the intereting quirks in VB.NET - I updated, including showing that it's really not necessary in the first place...
Reed Copsey
@Reed, you still cannot use `protected` in your example, because the interface method must be public. Nor can you use `override`, as you'll get an "no suitable method found to override" compiler error (unless the `GetService` implementation was also marked virtual, applies to the MyControl : Control case).
Anthony Pegram
@Anthony: Not true. I'm overriding Component.GetService here, which is protected virtual. After my initial snafu, I put this in a compiler to make sure it works (and it does). See: http://msdn.microsoft.com/en-us/library/system.componentmodel.component.getservice.aspx
Reed Copsey
@Reed, well, that will teach me to consider the actual objects being referenced instead of generalities. Oops. But yes, if `Control` (or it's bases) implements the interface explicity and provides a virtual method with a similar name, the code indeed works.
Anthony Pegram
@Anthony: Yeah, Windows.Forms.Control is implemented oddly, to say the least ;)
Reed Copsey
@Reed, though you would expect it, Component does not implement IServiceProvider. It does, however, have the GetService method.
Jules
+4  A: 

There is a bit of a corner issue with VB.Net interface implementation that needs to be considered when porting to C#. A implemented interface method in VB.Net essentially uses both implicit and explicit interface implementations in the same line. This allows for cases like mismatched names and non-public implementations.

For example the following is also a legal implementation of IServiceProvider

Class Example 
  Implements IServiceProvider

  Private Sub GetServiceWrongName(t As Type) As Object Implements IServiceProvider.GetService
    ...
  End Sub
End Class

It translates to roughly the following C# code

class Example : IServiceProvider {
  public object GetServiceWrongName(t as Type) {
    ..
  }

  object IServiceProvider.GetService(t as Type) {
    return GetServiceWrongName(t);
  }

}
JaredPar
Does it implement it this way, or implement the interface explicitly? I thought it was the latter...
Reed Copsey
@Reed, the code it actually produces is just not representable in C# at all. It generates a single method which has the IL op codes that specify it as the override to `IServiceProvider.GetService`. I find it's instructive to take my example, compile it and view the IL dump in reflector. The only way to get equivalent code in C# (non-public, different names, etc ...) is the two method approach.
JaredPar
@JaredPar: Very interesting. Thanks.
Reed Copsey
+2  A: 

The original VB.NET method is protected, so I guess it's the equivalent of explicit interface implementation in C#:

class MyControl : Control, IServiceProvider
{
     object IServiceProvider.GetService(Type t)
     {
         ...
     }
}
Thomas Levesque
Not equivalent to explicit implementation because you can call it from a reference to `MyControl` in VB.Net. The translation between the two can really only be expresed with a combination of implicit and explicit implementation.
JaredPar
Thats the one cheers. I tried everything but leaving off the name of the method.
Jules
@Jules: Just realize that this probably will not behave the way you want it to behave. See JaredPar or my answer for details...
Reed Copsey