views:

45

answers:

2

This question is a follow-up to my last question with a reference to COM Interop.

Let's say I have the following 2 interfaces and implementing classes:

public interface ISkuItem 
{ 
    public string SKU { get; set; } 
} 

public interface ICartItem : ISkuItem 
{ 
    public int Quantity { get; set; } 
    public bool IsDiscountable { get; set; } 
} 

public class CartItem : ICartItem
{
    //implemented properties...
}

Or, in VB.NET:

Public Interface ISkuItem
    Property SKU() As String
End Interface

Public Interface ICartItem
    Inherits ISkuItem
    Property Quantity() As Integer
    Property IsDiscountable() As Boolean
End Interface

Public Class CartItem
    Implements ICartItem

    'Implemented Properties'
End Class   

Interfaces are important in COM interop for exposing properties and methods to IntelliSense in the VB6 IDE (per this article). However, because ICartItem is inherited from ISkuItem, SKU is not explicitly defined in ICartItem and thus is not visible in IntelliSense in VB6 and even throws a compiler error when trying to write to objCartItem.SKU.

I've tried using Shadows and Overloads on the SKU property in ISkuItem, but then the compiler wants me to explicitly implement SKU for both ISkuItem and ICartItem within the CartItem class. I don't think that's what I want.

Is there a way (in either VB.NET or C#) to explicitly declare the SKU property in ICartItem without having to declare SKU twice in the CartItem class?

+2  A: 

Unless you need different implementations for each interface you really just want to implicitly define the implementations.

... C# ...

public interface ISkuItem
{
    string SKU { get; set; }
}
public interface ICartItem : ISkuItem
{
    new string SKU { get; set; }
}
public class CartItem : ICartItem
{
    public string SKU { get; set; }
}

... VB.Net ...

Public Interface ISkuItem
    Property SKU() As String
End Interface

Public Interface ICartItem
    Inherits ISkuItem
    Shadows Property SKU() As String
End Interface

Public Class CartItem
    Implements ICartItem

    Private _sku As String
    Public Property SKU() As String Implements ICartItem.SKU, ISkuItem.SKU
        Get
            Return _sku
        End Get
        Set(ByVal value As String)
            _sku = value
        End Set
    End Property

End Class
Matthew Whited
It looks so beautiful, but...it doesn't work in VB6. Oddly enough, the VB6 application throws an error in an earlier spot in the code, when trying to assign the CartItem object to equal the ICartItem object. Before, it would only throw the error when I tried to set the SKU property of the ICartItem object. Oh well, it was worth a try.
Ben McCormack
Well VB6 really isn't object-oriented. It wishes to be... but it's lacking in many areas.
Matthew Whited
+1  A: 

You could do as Matthew suggests and provide a new (Shadows) SKU member to ICartItem. But as I'm sure you realize, this pretty much renders your interface inheritance useless.

It really seems like this interface inheritance model isn't working out for you.

Are you sure that having ICartItem inherit from ISkuItem is actually buying you anything?

Rather than suffer a headache over it, I'd probably be inclined to just have ICartItem offer its own SKU property and not inherit from ISkuItem at all. Then any class implementing ICartItem could optionally also implement ISkuItem explicitly (just as many collection classes in .NET do, e.g. with ICollection<T> and ICollection); but either way it will have an SKU property.

This isn't the design choice I would make in general, mind you (I would go with what you have); but when it comes to COM interop, sometimes you just have to make sacrifices because you don't want to bang your head against the wall forever.

I'm not sure you're going to get a very satisfying answer on this one. VB6 just flat-out doesn't understand everything that .NET does, so you're not going to be able to figure out a perfect 1:1 mapping of .NET features to COM equivalents.

Dan Tao
You bring up several really good points. At the end of the day, you're correct in that a lot of this inheritance is causing a lot of unnecessary headaches when working with COM. Time to simplify it and move on.
Ben McCormack
As Dan says it may not be worth having `ICartItem` inherit from `ISkuItem`. But you may want the `CartItem` to implment both `ICartItem` and `ISkuItem`... of course we can't tell you what is required for your implmentation. If you have to have something that looks crazy to someone just so it works with your external app... then that is what you will have to do.
Matthew Whited