我想要做这件事:
interface IBase
{
string Property1 { get; }
}
interface IInherited : IBase
{
string Property1 { get; set; }
}
那么,如何让IInherited
具有继承的Property1
属性并添加允许set
的功能呢?
这是否可能?语法是什么?
编辑:请注意我将“inherited”一词加粗。 我特别询问如何继承该属性,而不是在新属性后面隐藏它。
我想要做这件事:
interface IBase
{
string Property1 { get; }
}
interface IInherited : IBase
{
string Property1 { get; set; }
}
那么,如何让IInherited
具有继承的Property1
属性并添加允许set
的功能呢?
这是否可能?语法是什么?
编辑:请注意我将“inherited”一词加粗。 我特别询问如何继承该属性,而不是在新属性后面隐藏它。
new
关键字,那么在我看来,你对接口的理解是错误的。确实,你可以说IInherited
“继承自”IBase
,但这究竟意味着什么?这些都是接口,它们建立代码合约。通过用new string Property1 { get; set; }
隐藏IBase.Property1
属性,你没有掩盖任何功能。因此,许多开发人员认为隐藏是“不好”的传统原因——它违反了多态性,在这种情况下是无关紧要的。interface IBase
{
string Property1 { get; }
}
interface IInherited : IBase
{
new string Property1 { set; }
}
IBase
,则可以读取它的Property1
属性。IInherited
,则可以读取它的Property1
属性(就像实现IBase
一样),并且还可以对其进行写操作。同样,这里没有什么问题。
IInherited
中,您可能只想声明 new string Property1 { set; }
。实现 IInherited
接口的类可以具有带有 getter 和 setter 的属性,并且它将实现两个接口。 - Timwistatic void M(IInherited x) { var read = x.Property1; }
原因是通过继承链在“稍后”声明的另一个名为 Property1
的属性隐藏了 IBase
的 Property1
。但该后置属性仅适用于 set
。我认为,new
修饰符基本上是错误的,因为它表示我们有一个不相关的属性。它不会“扩展”现有属性。另一种使用 new
属性中的 { get; set; }
的选择也不好,正如 @Timwi 所说。 - Jeppe Stig Nielsen((IInherited).Property1)
还是转换为((IBase).Property1)
,将会出现两种不同的结果。
没有明确的方法。你有两个选择:
public interface IBase
{
string Property1 { get; }
}
public interface IInherited : IBase
{
void SetProperty1(string value);
}
或者你可以使用new
关键字来消除编译器警告:
public interface IBase
{
string Property1 { get; }
}
public interface IInherited : IBase
{
new string Property1 { get; set; }
}
除非你显式实现 IInherited.Property1
,否则 IBase
将自动绑定到你的可设置实现。
new
即可。 - Adam Robinson不幸的是 - 属性本身不能被扩展。但是,您可以通过使用 new 来隐藏属性:
interface IInherited : IBase
{
// The new is actually unnecessary (you get warnings though), hiding is automatic
new string Property1 { get; set; }
}
或者,您可以创建自己的getter和setter方法,这些方法可以被覆盖(很好的Java风格):
interface IBase
{
string GetProperty1();
}
interface IInherited : IBase
{
void SetProperty1(string str);
}
属性实际上是由编译器转换为getter和setter方法。
你的代码应该可以正常工作... 只是因为隐藏了 Property1,所以会产生编译器警告。为了消除这个警告,请在 IInherited 中使用新前缀标记 Property1。
你可以使用 "new" 关键字标记属性,或者跳过继承:
public interface IBase
{
string Property1 { get; }
}
public interface IInherited : IBase
{
new string Property1 { get; set; }
}
或者:
public interface IBase
{
string Property1 { get; }
}
public interface IInherited
{
string Property1 { get; set; }
}
public class SomeClass : IInherited, IBase
{
public string Property1
{
get
{
// ...
}
set
{
// ...
}
}
}
我在工作中与几位主要开发人员进行了这样的对话,我们得出的结论是:
接口用于定义任何继承类可以执行的方法。即使您的第二个接口共享某些元素,或者甚至在某些相同的条件下使用,接口的定义也要讲解如何在与该接口相关的所有条件下使用类。
此外,出于这个原因,类能够继承多个接口。就代码清晰度而言:
public class SomeClass : IInherited, IBase