简体   繁体   English

从C#到VB.NET的实现接口

[英]Implementing Interface from C# to VB.NET

I had downloaded a C# project and wanted to work on VB.Net so I decided to convert that from C# to VB.NET and I encountered some problems when it came to implementing interfaces. 我已经下载了一个C#项目并想在VB.Net上工作,所以我决定将其从C#转换为VB.NET,在实现接口时遇到了一些问题。 I keep getting errors in VB.NET about implementation about how I must have Read-Only or Write-Only specifiers. 我在VB.NET中不断收到有关必须如何具有Read-OnlyRead-Only Write-Only说明符的实现的错误。 I want to get rid of this error but I don't know how I can achieve this. 我想摆脱这个错误,但我不知道该如何实现。

I have Three Files: 我有三个文件:

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

The same goes with C#, however in C# it works fine and I want to try to get it to work exactly like that in VB.net. C#也是如此,但是在C#中它可以正常工作,我想尝试使其完全像VB.net中的那样工作。

CustomPaintRichText.vb: 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: IUnderlineableSpellingControl.vb:

Public Interface IUnderlineableSpellingControl
   Inherits ISpellingControl
   Inherits IUnderlineable
End Interface

ISpellingControl.vb: 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

If I keep the cursor carret next to Implements IUnderlineableSpellingControl and hit ENTER key, within the CustomPaintRichText.vb class, I get: 如果将光标carret保留在Implements IUnderlineableSpellingControl旁边,并在CustomPaintRichText.vb类中按Enter键, Implements IUnderlineableSpellingControl得到:

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

And when I make changes to the CustomPaintRichText from a form, I will have extra additional controls and ultimately nothing works. 当我从表单对CustomPaintRichText进行更改时,我将获得额外的附加控件,最终将无济于事。

The error is in Implements IUnderlineableSpellingControl . 错误Implements IUnderlineableSpellingControl It is underlined saying that: 'CustomPaintRichText' must implement 'Event Disposed(sender As Object, e As System.EventArgs)' for interface 'ISpellingControl'. 强调指出:'CustomPaintRichText'必须为接口'ISpellingControl'实现'Event Disposed(sender as Object,e As System.EventArgs)'。 This is one of 30 errors along with the ..must implement..for interface. 这是..接口必须实现..的30个错误之一。

Here's the error list if you want to see what kind of errors I'm getting. 如果您想查看我遇到的错误类型,请参见以下错误列表

Here are the .cs files in case: 这是.cs文件,以防万一:

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

Congratulations, you made Hans Passant go "Ugh!" 恭喜,您让Hans Passant转到了“ U!” :) :)

Speaking to his point, though, mixing and matching assemblies compiled from VB, C#, C++/CLI, F#, or whatever, is generally encouraged in the .NET world, and is the practical solution to your problem. 说到他的观点,在.NET世界中通常鼓励混合和匹配从VB,C#,C ++ / CLI,F#或任何版本编译的程序集,这是解决问题的实用方法。 However, if you insist on transforming this C# project into its VB equivalent, one needs to understand the differences in how interfaces get implemented between these two languages. 但是,如果您坚持要将此C#项目转换为等效的VB,则需要了解这两种语言之间接口实现方式的差异。

C# has two styles of implementation: implicit and explicit (see http://blogs.msdn.com/b/mhop/archive/2006/12/12/implicit-and-explicit-interface-implementations.aspx ). C#有两种实现方式:隐式和显式(请参阅http://blogs.msdn.com/b/mhop/archive/2006/12/12/implicit-and-explicit-interface-implementations.aspx )。 VB has only an explicit style, which doesn't work quite the same as C# (see https://msdn.microsoft.com/en-us/library/28e2e18x.aspx ). VB仅具有显式样式,其功能与C#完全不同(请参阅https://msdn.microsoft.com/zh-cn/library/28e2e18x.aspx )。

All of those "must implement" errors mean pretty much what they say: You must use the Implements keyword on the appropriate members of your subclass, because VB doesn't do implicit implementations of interfaces. 所有这些“必须实现”错误几乎都说明了他们所说的话:您必须在子类的适当成员上使用Implements关键字,因为VB不会执行接口的隐式实现。 That's a C# thing. 那是C#的事情。 When you hit the ENTER key with the cursor caret next to Implements IUnderlineableSpellingControl , the IDE generated template code for the affected (apparently missing) members, complete with Implements . 当您用Implements IUnderlineableSpellingControl旁边的光标插入符号按ENTER键时,IDE会为受影响的(显然丢失)的成员生成模板代码,并带有Implements It did that in trying to be helpful, but in this case you have to look over the code and put in the Implements clauses where they're needed (and probably get rid off that template code). 它确实是在尝试提供帮助,但是在这种情况下,您必须查看代码并将其放在需要的Implements子句中(并可能摆脱该模板代码)。

C# has a neat implicit style where it will automatically "wire-up" implementations by matching member names between your class and the interfaces being implemented. C#具有简洁的隐式样式,它将通过在类和要实现的接口之间匹配成员名称来自动“连接”实现。 Should there be more than one interface that have the same member (with the same signature), they will all be implemented with the very same member in your class (see http://blogs.msdn.com/b/mhop/archive/2006/12/12/implicit-and-explicit-interface-implementations.aspx ). 如果有多个接口具有相同的成员(具有相同的签名),则将在您的类中使用相同的成员来实现所有接口(请参阅http://blogs.msdn.com/b/mhop/archive/ 2006/12/12 /隐式和显式接口implementations.aspx )。 This can be a wonderful or not-so-good thing depending on the situation. 根据情况,这可能是一件奇妙的事情,或不是那么好。

C# has a limited explicit style. C#具有有限的显式样式。 One simply defines a member in the named in the format of InterfaceName.MemberName (see https://msdn.microsoft.com/en-us/library/ms173157.aspx ). 只需简单地以InterfaceName.MemberName格式定义成员即可(请参阅https://msdn.microsoft.com/zh-cn/library/ms173157.aspx )。

VB has only its explicit style, but it allows for a list of interface members in the Implements clause so that they all get implemented by the very same member in your class. VB仅具有其显式的样式,但是它允许在Implements子句中使用一系列接口成员,以便它们都由类中的同一成员实现。 This is the work-around for C# implicit implementations that hookup multiple interfaces. 这是连接多个接口的C#隐式实现的解决方法。

Finally, there are some sources which claim that VB cannot do re-implementations of an interface on a subclass of a superclass that already has it implemented (eg http://www.dotnetheaven.com/article/how-to-re-implement-interfaces-in-vb.net ). 最后,有一些消息来源声称VB无法在已经实现它的超类的子类上重新实现接口(例如, http//www.dotnetheaven.com/article/how-to-re-implement) -interfaces-in-vb.net )。 I do not know if that was ever true, but I can aver that the VB of VS 2012 and later allows for such re-implementations. 我不知道这是否曾经是真的,但我可以断言VS 2012及更高版本的VB允许这种重新实现。

C# allows you to implement a WriteOnly or ReadOnly property with a read/write property. C#允许您使用读/写属性实现WriteOnly或ReadOnly属性。 (VB 2015 also allows this). (VB 2015也允许这样做)。 You can easily work around this prior to VB 2015 - here's an example for your IsPasswordProtected implementation: 您可以在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

The 'Implements' goes on the new ReadOnly property which calls the existing read/write property. “实现”位于新的ReadOnly属性上,该属性调用现有的read / write属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM