Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VB.NET类继承基类并实现接口问题(适用于C#)_C#_Vb.net - Fatal编程技术网

VB.NET类继承基类并实现接口问题(适用于C#)

VB.NET类继承基类并实现接口问题(适用于C#),c#,vb.net,C#,Vb.net,我试图在VB.NET中创建一个类,该类继承了一个基本抽象类并实现了一个接口。接口声明一个名为Description的字符串属性。基类包含一个名为Description的字符串属性。主类继承基类并实现接口。基类中描述属性的存在满足接口要求。这在C#中运行良好,但在VB.NET中会导致问题 首先,这里是一个C代码的例子,它可以工作: public interface IFoo { string Description { get; set; } } public abstract clas

我试图在VB.NET中创建一个类,该类继承了一个基本抽象类并实现了一个接口。接口声明一个名为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版本:

公共接口IFoo
属性描述()为字符串
端接口
公共MustInherit类FooBase
私有\u描述为字符串
公共属性描述()为字符串
得到
返回描述
结束
设置(ByVal值作为字符串)
_描述=值
端集
端属性
末级
公共类MyFoo
继承FooBase
实现IFoo
末级
如果我让基类(
FooBase
)实现接口并将
Implements IFoo.Description
添加到属性中,这一切都很好,但我不希望基类实现接口

编译器错误为:

类“MyFoo”必须为接口“IFoo”实现“属性描述()为字符串”。实现属性必须具有匹配的“ReadOnly”或“WriteOnly”说明符


VB.NET是否可以不处理此问题,或者我是否需要在某个地方更改语法以使其正常工作?

无论如何,您必须指定IFoo接口的实现细节

这个简单的选择怎么样

公共类MyFoo
继承FooBase
实现IFoo
重载属性Description(),因为字符串实现了IFoo.Description
得到
返回MyBase.Description
结束
设置(ByVal值作为字符串)
MyBase.Description=值
端集
端属性
末级

您需要在基类中将属性标记为
可重写
必须重写
,然后您可以在子类中将其重写:

Public必须继承类FooBase
私有\u描述为字符串
作为字符串的公共可重写属性描述()
得到
返回描述
结束
设置(ByVal值作为字符串)
_描述=值
端集
端属性
末级
公共类MyFoo
继承FooBase
实现IFoo
Public重写属性Description(),因为字符串实现了IFoo.Description
得到
返回MyBase.Description
结束
设置(ByVal值作为字符串)
MyBase.Description=值
端集
端属性
末级
编辑 这是对@M.A.哈宁发布的内容的回应。我们的两种解决方案都有效,但了解每种解决方案的后果很重要。想象一下下面的代码:

Dim X As FooBase=New MyFoo()
Trace.WriteLine(X.Description)
从X.描述中得到了什么?使用可重写方法可以获得对子类的调用,而使用重载方法可以获得对基类的调用。这两者都不是对的,也不是错的,重要的是理解宣言的后果。使用重载方法,您必须向上强制转换以获得子级的实现:

Trace.WriteLine(DirectCast(X,MyFoo.Description)

如果您只是从子类调用MyBase.Description,那么这个问题是没有意义的,但是如果您更改了子类的定义,那么您只需要确保您了解发生了什么。

这是一个奇怪的问题,它清楚地显示了C#和VB.NET编译器之间的差异。我建议您在抽象基类上实现接口,因为这将使VB.NET编译器感到高兴,并且在执行时,您的子类仍将具有元数据,表明它实际上实现了
IFoo


子类必须是声明它实现接口的子类,这有什么具体原因吗?

VB要求实现属性声明实现。这是因为我实际上认为VB中的一个很好的特性,有时我在C语言中漏掉了——您可以重命名实现接口成员的成员。

因此,在
FooBase
中实现
IFoo.Description
的唯一方法是声明
Description
可重写
,然后将
MyFoo
定义为:

公共类MyFoo
继承FooBase
实现IFoo
Public重写属性Description(),因为字符串实现了IFoo.Description
得到
返回MyBase.Description
结束
设置(ByVal值作为字符串)
MyBase.Description=值
端集
端属性
末级

VB.NET不支持隐式实现。 我也遇到了这个问题,遇到了很多麻烦

当您使用生成的类(实体等)时,您必须显式声明
实现IFoo
,这使得它根本不可能实现


因此,我希望您投票,下一版本的VB将改进编译器,使其更加智能。

如果我参加聚会迟到,我将表示歉意,如果此功能仅在.NET 4中引入,我也表示歉意,但以下是可能的(现在)

公共接口IFoo
属性描述()为字符串
端接口
公共MustInherit类FooBase
实现IFoo
当字符串实现IFoo.Description时,Public MustOverride属性描述
末级
公共类MyFoo
继承FooBase
私有\u描述为字符串
Public将属性描述重写为字符串
得到
返回描述
结束Ge