我试图在VB.NET中创建一个继承基本抽象类的类,并实现一个接口 . 接口声明一个名为Description的字符串属性 . 基类包含一个名为Description的字符串属性 . 主类继承基类并实现接口 . 基类中存在Description属性可满足接口要求 . 这在C#中工作正常但在VB.NET中引起问题 .
首先,这是一个有效的C#代码示例:
public interface IFoo
{
string Description { get; set; }
}
public abstract class FooBase
{
public string Description { get; set; }
}
public class MyFoo : FooBase, IFoo
{
}
现在这是VB.NET版本,它给出了编译器错误:
Public Interface IFoo
Property Description() As String
End Interface
Public MustInherit Class FooBase
Private _Description As String
Public Property Description() As String
Get
Return _Description
End Get
Set(ByVal value As String)
_Description = value
End Set
End Property
End Class
Public Class MyFoo
Inherits FooBase
Implements IFoo
End Class
如果我使基类( FooBase
)实现接口并将 Implements IFoo.Description
添加到属性都很好,但我不希望基类实现接口 .
编译器错误是:
类'MyFoo'必须为接口'IFoo'实现'Property Description()As String' . 实现属性必须具有匹配的“ReadOnly”或“WriteOnly”说明符 .
VB.NET不能处理这个问题,还是我需要在某个地方更改语法才能使其工作?
7 回答
您需要在基类中将属性标记为
Overridable
或MustOverride
,然后您可以在子类中覆盖它:Edit 这是对@ M.A的回应 . 哈宁发布了 . 我们的两个解决方案都有效,但了解每个解决方案的后果非常重要 . 想象一下以下代码:
什么来自X.Description?使用Overridable,您将使用Overload方法调用子类,您将获得对基类的调用 . 无论是对还是错,它对于理解宣言的后果非常重要 . 使用重载方法,您必须向上转换才能获得子项的实现:
如果您只是从子类调用MyBase.Description,那么这个问题没有实际意义,但是如果您更改了子类的定义,那么您只需要确保了解正在发生的事情 .
无论如何,您必须指定IFoo接口的实现细节 .
这个简单的选择怎么样?
VB要求实现属性声明实现 . 这是因为我实际上认为我在C#中有时会错过的一个很好的功能 - 您可以重命名实现接口成员的成员 .
因此,如果不在
FooBase
中实现IFoo.Description
,使这项工作的唯一方法是声明Description
Overridable
,然后将MyFoo
定义为:对不起,如果我迟到了,并且如果只在.NET 4中引入了此功能,也会道歉,但以下是可能的(现在)
VB.NET不支持隐式实现 . 我也遇到了这个问题并且遇到了很多麻烦 .
当您使用生成的类(实体等)时,您必须明确声明
Implements IFoo
,这使它根本不可能 .因此I submitted a connection to Microsoft我希望你能投票和VB的下一版本,他们将改进编译器更聪明 .
由于我的代表,我无法对M.A. Hanin的答案发表评论,但我建议进行一些小调整以避免编译器警告隐藏基本方法,假设您不希望或不能覆盖基类中的属性 .
这是一个奇怪的问题,它清楚地表明了C#和VB.NET编译器之间的区别 . 我建议你在抽象基类上实现接口,因为这会使VB.NET编译器感到高兴,并且在执行时你的子类仍然会有元数据,表明它确实实现了
IFoo
.是否有一个特定的原因,子类必须是声明它实现接口的子类?