【问题标题】:Accommodate Parameterized Methods from VB.Net in C# Interface在 C# 接口中容纳来自 VB.Net 的参数化方法
【发布时间】:2019-07-02 20:23:59
【问题描述】:

我们将之前在 VB.Net 中的接口移动到一个单独的 C# 项目中,该项目应该包含由相应的 VB.Net 类实现的接口。尝试从包含参数化属性的 VB.Net 移动接口定义时会出现问题。

我尝试过这样的事情:

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

但是,get_MyPropertyMyProperty 都不会显示为依赖项目的可实现方法/属性。将参数化属性移动到方法将需要大量重构,并且会是最坏情况下的工作。我们正在寻找可以得到的任何替代方案。

【问题讨论】:

  • 这在 C# 中是不可能的,所以我不确定你想要什么“替代品”。您唯一能做的就是将它们全部转换为方法。我不确定你为什么说你的第一个例子没有出现在依赖项目中,但它对我来说似乎是一个有效的接口方法。唯一的另一种选择是将所有内容保留在 VB 中并从 C# 中调用。

标签: c# vb.net


【解决方案1】:

VB 接口

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

由VB实现

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

通过 C#

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

C# 接口

interface MyInterface
{
    short get_MyProperty(short parameter);
}

在 C# 中的实现方式与 VB 接口相同

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

在 VB 中,实现看起来像带有 get_ 方法的 C#,不再是 ReadOnly 属性

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

而且由于 C# 没有参数化属性,所以这是不可能的。

但是为什么首先将接口转移到 C# 中呢?带有接口的小型 VB.NET 程序集并不难管理。如果您想减少装运组件的数量,例如使用ILMerge 也不会太困难。

嘿,值得保留只是为了向 C# 展示 VB.NET 有时有多棒。

【讨论】:

  • 我们的大部分代码都是用 C# 编写的,只是我们正在使用的这个项目给我们带来了问题。我们试图避免编写更多的 VB.Net 代码。感谢您的帮助!
【解决方案2】:

如果您只是担心代码的外观(而不是尝试实现协定),您可以通过为索引属性开发一个小型包装类来获得所需的内容。

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);
        }
    }
}

一旦你有了那个类,你就可以像这样实现一个“索引属性”:

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;
                }
            );
        }
    }
}

现在你可以用熟悉的方式调用它了:

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

输出:

3

DotNetFiddle上查看我的示例

注意:虽然上面的东西会起作用,但“正确”的答案是更改您的代码以使用惯用的 c#,而忘记 VB.NET 的工作方式。这意味着您应该使用方法或使用稍微不同的对象模型。

【讨论】:

  • 谢谢,虽然我真的只需要一种方法来维护索引属性的合同以供 VB.Net 使用
  • 唉,那你就完蛋了。请参阅 this question 以获取 Eric Lippert 关于为什么 c# 不支持索引属性的答案。
猜你喜欢
  • 2012-02-24
  • 2014-07-02
  • 2013-12-28
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
相关资源
最近更新 更多