【问题标题】:Implementing Interface from C# to VB.NET从 C# 到 VB.NET 的实现接口
【发布时间】:2015-09-30 23:58:48
【问题描述】:

我下载了一个 C# 项目并想在 VB.Net 上工作,所以我决定将它从 C# 转换为 VB.NET,但在实现接口时遇到了一些问题。我在 VB.NET 中不断收到关于我必须如何使用 Read-OnlyWrite-Only 说明符的错误。我想摆脱这个错误,但我不知道如何实现这一点。

我有三个文件:

  1. CustomPaintRichText.vb
  2. IUnderlineableSpellingControl.vb
  3. ISpellingControl.vb

C# 也是如此,但是在 C# 中它可以正常工作,我想尝试让它在 VB.net 中完全一样地工作。

CustomPaintRichText.vb:

Public Class CustomPaintRichText
Inherits RichTextBox
Implements IUnderlineableSpellingControl

Public m_underlinedSections As Dictionary(Of Integer, Integer)
Public m_protectedSections As Dictionary(Of Integer, Integer)
Public m_ignoredSections As Dictionary(Of Integer, Integer)
Public Property UnderlinedSections() As Dictionary(Of Integer, Integer)
    Get
        If m_underlinedSections Is Nothing Then
            m_underlinedSections = New Dictionary(Of Integer, Integer)()
        End If
        Return m_underlinedSections
    End Get
    Set(value As Dictionary(Of Integer, Integer))
        m_underlinedSections = value
    End Set
End Property

Public WriteOnly Property ProtectedSections() As Dictionary(Of Integer, Integer)
    Set(value As Dictionary(Of Integer, Integer))
        m_protectedSections = value
    End Set
End Property

Public WriteOnly Property IgnoredSections() As Dictionary(Of Integer, Integer)
    Set(value As Dictionary(Of Integer, Integer))
        m_ignoredSections = value
    End Set
End Property

Private spellingEnabled As Boolean
Private spellingAutoEnabled As Boolean
Private m_isPassWordProtected As Boolean

Private penColour As Pen
Public Property WhatPenColour() As Pen
    Get
        Return penColour
    End Get
    Set(value As Pen)
        penColour = value
    End Set
End Property

Public Property IsSpellingEnabled() As Boolean
    Get
        Return spellingEnabled
    End Get
    Set(value As Boolean)
        spellingEnabled = value
    End Set
End Property

Public Property IsSpellingAutoEnabled() As Boolean
    Get
        Return spellingAutoEnabled
    End Get
    Set(value As Boolean)
        spellingAutoEnabled = value
        If Not spellingEnabled Then
            spellingEnabled = value
        End If
    End Set
End Property

Public Property IsPassWordProtected() As Boolean
    Get
        Return m_isPassWordProtected
    End Get
    Set(value As Boolean)
        m_isPassWordProtected = value
    End Set
End Property
End Class

IUnderlineableSpellingControl.vb:

Public Interface IUnderlineableSpellingControl
   Inherits ISpellingControl
   Inherits IUnderlineable
End Interface

ISpellingControl.vb:

Public Interface ISpellingControl
<Browsable(True)> _
Property IsSpellingEnabled() As Boolean
Property SelectionStart() As Integer
Property SelectionLength() As Integer
Property SelectedText() As String
Property Text() As String
Property ContextMenuStrip() As ContextMenuStrip
Property WhatPenColour() As Pen
Property Parent() As Control
Event Disposed As EventHandler
Event Enter As EventHandler
Event TextChanged As EventHandler
Property [ReadOnly]() As Boolean
ReadOnly Property IsPassWordProtected() As Boolean
Sub Cut()
Sub Copy()
Sub Paste(clipFormat As DataFormats.Format)
Sub [Select](start As Integer, length As Integer)
Function Focus() As Boolean
Sub Invalidate(invalidateChildren As Boolean)
WriteOnly Property IgnoredSections() As Dictionary(Of Integer, Integer)
End Interface

如果我将光标放在 Implements IUnderlineableSpellingControl 旁边并按 ENTER 键,在 CustomPaintRichText.vb 类中,我会得到:

Public Property ContextMenuStrip1 As ContextMenuStrip Implements ISpellingControl.ContextMenuStrip

Public Sub Copy1() Implements ISpellingControl.Copy

End Sub

Public Sub Cut1() Implements ISpellingControl.Cut

End Sub

Public Event Disposed1(sender As Object, e As EventArgs) Implements ISpellingControl.Disposed

Public Event Enter1(sender As Object, e As EventArgs) Implements ISpellingControl.Enter

Public Function Focus1() As Boolean Implements ISpellingControl.Focus

End Function

Public WriteOnly Property IgnoredSections1 As Dictionary(Of Integer, Integer) Implements ISpellingControl.IgnoredSections
    Set(value As Dictionary(Of Integer, Integer))

    End Set
End Property

Public Sub Invalidate1(invalidateChildren As Boolean) Implements ISpellingControl.Invalidate

End Sub

Public ReadOnly Property IsPassWordProtected1 As Boolean Implements ISpellingControl.IsPassWordProtected
    Get

    End Get
End Property

Public Property IsSpellingEnabled1 As Boolean Implements ISpellingControl.IsSpellingEnabled

Public Property Parent1 As Control Implements ISpellingControl.Parent

Public Sub Paste1(clipFormat As DataFormats.Format) Implements ISpellingControl.Paste

End Sub

Public Property ReadOnly1 As Boolean Implements ISpellingControl.ReadOnly

Public Sub Select1(start As Integer, length As Integer) Implements ISpellingControl.Select

End Sub

Public Property SelectedText1 As String Implements ISpellingControl.SelectedText

Public Property SelectionLength1 As Integer Implements ISpellingControl.SelectionLength

Public Property SelectionStart1 As Integer Implements ISpellingControl.SelectionStart

Public Property Text1 As String Implements ISpellingControl.Text

Public Event TextChanged1(sender As Object, e As EventArgs) Implements ISpellingControl.TextChanged

Public Property WhatPenColour1 As Pen Implements ISpellingControl.WhatPenColour

Public Sub CustomPaint1() Implements IUnderlineable.CustomPaint

End Sub

Public Property IsSpellingAutoEnabled1 As Boolean Implements IUnderlineable.IsSpellingAutoEnabled

Public Event KeyDown1(sender As Object, e As KeyEventArgs) Implements IUnderlineable.KeyDown

Public WriteOnly Property ProtectedSections1 As Dictionary(Of Integer, Integer) Implements IUnderlineable.ProtectedSections
    Set(value As Dictionary(Of Integer, Integer))

    End Set
End Property

Public Sub RemoveWordFromUnderliningList1(wordStart As Integer) Implements IUnderlineable.RemoveWordFromUnderliningList

End Sub

Public Event SelectionChanged1(sender As Object, e As EventArgs) Implements IUnderlineable.SelectionChanged

Public Property UnderlinedSections1 As Dictionary(Of Integer, Integer) Implements IUnderlineable.UnderlinedSections

当我从表单更改 CustomPaintRichText 时,我将拥有额外的控件,但最终没有任何效果。

错误位于Implements IUnderlineableSpellingControl。下划线表示:“CustomPaintRichText”必须为接口“ISpellingControl”实现“Event Disposed(sender As Object, e As System.EventArgs)”。这是 ..must implement..for 接口的 30 个错误之一。

这里是error list,如果你想看看我遇到了什么样的错误。

以下是 .cs 文件以防万一:

  1. CustomPaintRichText.cs
  2. IUnderlineableSpellingControl.cs
  3. ISpellingControl.cs

【问题讨论】:

  • 那堵巨大的代码墙哪里有错误?接口说明符错误应该是编译器错误,但“没有用”听起来像是编译。
  • Option Explicit on 看看能不能编译?
  • Interface 不是魔法——这些方法或属性体中没有任何代码,所以它们不会做任何事情来解释为什么“没有任何作用”
  • @Plutonix 该死,对不起,我写问题的时候好像忘记了。
  • 呃,你为什么要这样浪费你(和我们)的时间?只需将 C# 项目添加到您的解决方案中。在您的 VB.NET 项目中添加对它的项目引用。

标签: vb.net interface implements


【解决方案1】:

恭喜,你让 Hans Passant 发出“啊!” :)

不过,说到他的观点,混合和匹配从 VB、C#、C++/CLI、F# 或其他任何东西编译的程序集在 .NET 世界中通常受到鼓励,并且是解决您的问题的实用解决方案。但是,如果您坚持将这个 C# 项目转换为它的 VB 等效项目,则需要了解这两种语言之间接口实现方式的差异。

C# 有两种实现方式:隐式和显式(参见http://blogs.msdn.com/b/mhop/archive/2006/12/12/implicit-and-explicit-interface-implementations.aspx)。 VB 只有一个明确的样式,它的工作方式与 C# 不太一样(请参阅https://msdn.microsoft.com/en-us/library/28e2e18x.aspx)。

所有这些“必须实现”错误的含义与他们所说的差不多:您必须在子类的适当成员上使用 Implements 关键字,因为 VB 不执行接口的隐式实现。那是 C# 的事情。当您使用 Implements IUnderlineableSpellingControl 旁边的光标插入键按 ENTER 键时,IDE 会为受影响的(显然缺失的)成员生成模板代码,并以 Implements 完成。它这样做是为了提供帮助,但在这种情况下,您必须查看代码并将 Implements 子句放在需要它们的地方(并且可能摆脱该模板代码)。

C# 有一种简洁的隐式风格,它会通过匹配你的类和正在实现的接口之间的成员名称来自动“连接”实现。如果有多个接口具有相同的成员(具有相同的签名),它们都将在您的类中使用相同的成员来实现(参见http://blogs.msdn.com/b/mhop/archive/2006/12/12/implicit-and-explicit-interface-implementations.aspx)。视情况而定,这可能是一件好事,也可能不是那么好。

C# 具有有限的显式风格。一个简单地以 InterfaceName.MemberName 的格式定义命名的成员(请参阅https://msdn.microsoft.com/en-us/library/ms173157.aspx)。

VB 只有其明确的样式,但它允许在Implements 子句中列出接口成员,以便它们都由类中的同一个成员实现。这是连接多个接口的 C# 隐式实现的解决方法。

最后,有一些消息来源声称 VB 无法在已经实现的超类的子类上重新实现接口(例如http://www.dotnetheaven.com/article/how-to-re-implement-interfaces-in-vb.net)。我不知道这是否是真的,但我可以断言 VS 2012 及更高版本的 VB 允许这样的重新实现。

【讨论】:

  • 我认为我应该为我让 Hans Passant 所做的事情获得更多的代表。我得出的结论是,我应该坚持使用 C#,但我确实很欣赏详尽的解释。
【解决方案2】:

C# 允许您使用读/写属性实现 WriteOnly 或 ReadOnly 属性。 (VB 2015 也允许这样做)。 您可以在 VB 2015 之前轻松解决此问题 - 这是您的 IsPasswordProtected 实现的示例:

Private ReadOnly Property ISpellingControl_IsPassWordProtected() As Boolean Implements ISpellingControl.IsPassWordProtected
    Get
        Return IsPassWordProtected
    End Get
End Property
Public Property IsPassWordProtected() As Boolean
    Get
        Return isPassWordProtected_Renamed
    End Get
    Set(ByVal value As Boolean)
        isPassWordProtected_Renamed = value
    End Set
End Property

“Implements”位于调用现有读/写属性的新 ReadOnly 属性上。

【讨论】:

  • 谢谢 Dave,我希望你没有花太多时间来回答这个问题。我将保留此作为将来的参考。
  • 没问题 - 但不要被本论坛中的其他人吓倒。 VB 中的接口实现问题只是一个中等复杂的 C# 到 VB 转换问题——这个论坛的人对转换问题的容忍度很低。
  • 谢谢你让我知道 :)
猜你喜欢
  • 2011-04-11
  • 2013-04-12
  • 2014-02-15
  • 2016-03-10
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
相关资源
最近更新 更多