views:

606

answers:

8

This seems like a reasonable (and maybe simple?) scenario, but how would you do the following:

Lets say I have 2 interfaces:

Interface ISimpleInterface
    string ErrorMsg { get; } 
End Interface

Interface IExtendedInterface
    string ErrorMsg { get; set; }    
    string SomeOtherProperty { get; set; }
End Interface

I want a class to implement both interfaces:

Public Class Foo Implements ISimpleInterface, IExtendedInterface

How do I define the ErrorMsg property in the class given that each interface has a different access level?

Here is my scenario in case you are wondering: I am writing a UserControl using a psuedo MVC arhitecture, where the UserControl exposes the extended interface to it's Controller, and exposes the Simple interface to the Consumers of the control.

By the way, implementing this in VB.NET (any suggested synatx in vb would be appreciated).

+4  A: 

You can implement one of them or both interfaces with an 'explicit interface' implementation, so the compiler knows which ErrorMsg property belongs to which interface.

To do this simply write :ISimpleInterface (for C#) after your class name and then click on ISimpleInterface and select implement explicit interface.

More information here: http://msdn.microsoft.com/en-us/library/aa288461(VS.71).aspx

Patrick Klug
You don't "need" to in this case - an implicit ErrorMsg {get;set;} will satisfy both, as long as they have the same intent.
Marc Gravell
right, thanks. corrected it.
Patrick Klug
A: 

You will need to work with Explicit Interface Implementations. More on the subject here: http://msdn.microsoft.com/en-us/library/aa288461(VS.71).aspx

Gerrie Schenck
+2  A: 

Sorry but I don't master VB.Net syntax.

In C# you can implement interfaces implicitly or explicitly. If your class Foo implements ErrorMsg as a public method, this implementation will be used for both interface.

If you want distinct implementation you can implement it explicitly :

string ISimpleInterface.ErrorMsg {get { ... } } 
string IExtendedInterface.ErrorMsg {get { ... } set { ... }}
Think Before Coding
+1  A: 

In C#, an implicit implementation (with the set) can satisfy both of these:

class Foo : ISimpleInterface, IExtendedInterface
{
    public string ErrorMsg { get; set; } 
    public string SomeOtherProperty {get; set;}
}

If you want to change it, you can use explicit implementation ("Implements" in VB?) - in C#:

string ISimpleInterface.ErrorMsg
{
    get { return ErrorMsg; } // or something more interesting
}
Marc Gravell
+2  A: 

In C# you can use explicit interface implementation:

class Foo
{
 string ISimpleInterface.ErrorMsg
 { get... }

 string IExtendedInterface.ErrorMsg
 { get... set... }

 string IExtendedInterface.SomeOtherProperty
 { get... set... }
}

or Interface Mapping

class Foo
{
 public string ErrorMsg
 { get... set... }  

 public string SomeOtherProperty
 { get... set... }
}

As for VB.NET, it has Implements keyword:

Property ErrorMsg As String Implements ISimpleInterface.ErrorMsg

Property OtherErrorMsg As String Implements IExtendedInterface.ErrorMsg
Anton Gogolev
How do I do this in VB.NET without 'ErrorMsg' property having to be spelled 2 different ways in the class implementation?
I guess something like `Implements ISimpleInterface.ErrorMsg, Implements IExtendedInterface.ErrorMsg`, though I'm not sure.
Anton Gogolev
I dont believe VB.NET works unless 'ErrorMsg' is spelled two different ways as in your example, i.e. 'OtherErrorMsg'
+1  A: 

The Implements keyword in VB.NET makes this easy:

Public Interface ISimpleInterface
  ReadOnly Property ErrorMsg() As String
End Interface

Friend Interface IExtendedInterface
  Property ErrorMsg() As String
  Property SomeOtherProperty() As String
End Interface

Public Class Foo
  Implements ISimpleInterface, IExtendedInterface
  Private other As String
  Private msg As String

  Public Property ErrorMsgEx() As String Implements IExtendedInterface.ErrorMsg
    Get
      Return msg
    End Get
    Set(ByVal value As String)
      msg = value
    End Set
  End Property

  Public Property SomeOtherPropertyEx() As String Implements IExtendedInterface.SomeOtherProperty
    Get
      Return other
    End Get
    Set(ByVal value As String)
      other = value
    End Set
  End Property

  Public ReadOnly Property ErrorMsg() As String Implements ISimpleInterface.ErrorMsg
    Get
      Return msg
    End Get
  End Property
End Class
Hans Passant
So am I forced to rename the property to 'ErrorMsgEx' ? I was hoping to preserve the Property name so that it is consistent amoung both implementations
No see my answer.
RS Conley
Which implementation property you rename doesn't really matter. Key is that the property is still named "ErrorMsg" when you use either interface.
Hans Passant
A: 

You can have private subroutines implement interfaces. It is only exposed when the object is assigned to a variable of that interface type.

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim S As ISimpleInterface
        Dim Ext As IExtendedInterface
        Dim F As New Foo
        F.ErrorMsg = "Test Error"
        S = F
        Ext = F
        MsgBox(S.ErrorMsg)
        MsgBox(Ext.ErrorMsg)
        MsgBox(F.ErrorMsg)
    End Sub
End Class


Public Interface ISimpleInterface
    ReadOnly Property ErrorMsg() As String
End Interface

Public Interface IExtendedInterface
    Property ErrorMsg() As String
    Property SomeOtherProperty() As String
End Interface

Public Class Foo
    Implements ISimpleInterface, IExtendedInterface
    Private other As String
    Private msg As String

    Public Property ErrorMsg() As String Implements IExtendedInterface.ErrorMsg
        Get
            Return msg
        End Get
        Set(ByVal value As String)
            msg = value
        End Set
    End Property

    Public Property SomeOtherProperty() As String Implements IExtendedInterface.SomeOtherProperty
        Get
            Return other
        End Get
        Set(ByVal value As String)
            other = value
        End Set
    End Property

    Private ReadOnly Property ErrorMsgSimple() As String Implements ISimpleInterface.ErrorMsg
        Get
            Return ErrorMsg
        End Get
    End Property
End Class
RS Conley
A: 

While explicit implementation will solve this, as shown by others, in this very case i would probably let IExtendedInterface implement ISimpleInterface (ErrorMsg property is semantically the same property, it means the same in these 2 interfaces i would guess).

interface ISimpleInterface
{
    string ErrorMessage { get; set; }
}
interface IExtendedInterface : ISimpleInterface
{
    string SomeOtherProperty { get; set; }
}
baretta