0

We are moving interfaces previously in VB.Net into a separate C# project, which should hold interfaces to be implemented by corresponding VB.Net classes. The issue comes when trying to move interface definitions from VB.Net which contain parameterized properties.

I've tried something like this:

C#:

    public interface MyInterface
    {
        short get_MyProperty(short parameter);
    }

VB.Net:

    Public ReadOnly Property MyProperty(ByVal Parameter As Short) As Short 
            Implements CSharpProject.MyInterface.MyProperty
        Get
            ' Do stuff
        End Get
    End Property

However, neither get_MyProperty nor MyProperty show up as implementable methods/properties to the dependent project. Moving the parameterized properties to methods would take a large amount of refactoring, and would be a worst-case-scenario effort. We're looking for any alternatives we can get.

RecyclingBen
  • 310
  • 3
  • 9
  • 1
    This isn't possible in C#, so I'm not sure what "alternatives" you want. The only thing you can do is to convert them all to methods. I'm not sure why you say that the first example you have isn't showing up in a dependent project though, it looks like a valid interface method to me. The only other alternative is to leave everything in VB and call it from C#. – Ron Beyer Jul 02 '19 at 20:39
  • Possible duplicate of [Interface implementation in C# and VB.NET](https://stackoverflow.com/questions/16105040/interface-implementation-in-c-sharp-and-vb-net) – Edney Holder Jul 02 '19 at 21:20

2 Answers2

0

The VB Interface

Interface MyInterface
    ReadOnly Property MyProperty(parameter As Short) As Short
End Interface

is Implemented by VB

Class MyVbClass
    Implements MyInterface
    Public ReadOnly Property MyProperty(parameter As Short) As Short _
        Implements MyInterface.MyProperty
        Get
        End Get
    End Property
End Class

and by C#

class MyCsClass : MyInterface
{
    public short get_MyProperty(short parameter) { }
}

The C# interface

interface MyInterface
{
    short get_MyProperty(short parameter);
}

is implemented the same way in C# as the VB Interface

class MyCsClass : MyInterface
{
    public short get_MyProperty(short parameter) { }
}

and in VB the Implementation looks like C# with the get_ method, no longer being a ReadOnly Property

Class MyVbClass
    Implements ClassLibrary1.MyInterface
    Public Function get_MyProperty(parameter As Short) As Short _
        Implements MyInterface.get_MyProperty
    End Function
End Class

and since C# has no parameterized properties, then it is not possible.

But why move the interfaces to C# in the first place? A small VB.NET assembly with interfaces isn't too difficult to manage. If you are trying to reduce the number of shipped assemblies it also isn't too difficult using ILMerge for example.

Hey, it's worth keeping around just to show C# how great VB.NET is sometimes.

djv
  • 15,168
  • 7
  • 48
  • 72
  • Much of our code is written in C#, it is just this project we're working with that is giving us issues. We're trying to avoid writing any more VB.Net code. Thanks for your help! – RecyclingBen Jul 02 '19 at 23:00
0

If you're just worried about the way the code looks (and not trying to implement a contract), you can essentially get what you need by developing a small wrapper class for indexed properties.

class IndexedProperty<TIndexer,TValue>
{
    protected readonly Func<TIndexer,TValue> _getter;
    protected readonly Action<TIndexer,TValue> _setter;

    public IndexedProperty(Func<TIndexer,TValue> getter, Action<TIndexer,TValue> setter)
    {
        _getter = getter;
        _setter = setter;
    }

    public TValue this[TIndexer parameter]
    {
        get 
        {
            return _getter(parameter);
        }
        set
        {
            _setter(parameter, value);
        }
    }
}

Once you have that class, you can implement an "indexed property" like this:

class Foo
{ 
    private short[] _backingStore = new short[10];

    public IndexedProperty<short, short> MyProperty
    { 
        get
        {
            return new IndexedProperty<short,short>
            (
                getter: key => 
                {
                    //Getter logic goes here. Example:
                    return _backingStore[key];  
                },
                setter: (key, val) =>
                {
                    //Setter logic goes here. Example:
                    _backingStore[key] = val;
                }
            );
        }
    }
}

Now you can call it in the familiar way:

var foo = new Foo();
foo.MyProperty[5] = 3;
Console.WriteLine(foo.MyProperty[5]);

Output:

3

See my example on DotNetFiddle

Note: While the above stuff will work, the "right" answer is to change your code to use idiomatic c# and forget about the way VB.NET worked. Meaning you ought to be using methods or using a slightly different object model.

John Wu
  • 50,556
  • 8
  • 44
  • 80
  • Thanks, though I really just need a way of maintaining the contract of indexed properties for use by VB.Net – RecyclingBen Jul 02 '19 at 22:50
  • Alas, you're screwed then. See [this question](https://stackoverflow.com/questions/2806894/why-c-sharp-doesnt-implement-indexed-properties) for an Eric Lippert answer on why c# doesn't support indexed properties. – John Wu Jul 02 '19 at 22:51