Sys*_*Lol 6 c# inheritance interface
是否建议在派生接口中使用"new"关键字为具有相同名称的属性或方法提供更多派生的返回值?
假设我有一个接口IDocument:
public interface IDocument
{
IParagraphs Paragraphs { get; }
IRevisions Revisions { get; }
IStyles Styles { get; }
}
Run Code Online (Sandbox Code Playgroud)
并派生出一个IRtfDocument.
public interface IRtfDocument: IDocument
{
string Rtf { get; }
...
}
Run Code Online (Sandbox Code Playgroud)
我还有更多派生的IParagraphs,IRevisions和IStyles接口:IRtfParagraphs,IRtfRevisions,IRtfStyles.许多特定于RTF的需求推动了他们的创建.
当我访问RTF文档的段落时,我想避免将它们转换为IRtfParagraphs.修订和样式也一样.避免同时使用"IRtfParagraphs"和"IParagraphs"也是很好的.所以我什么喜欢做的是这样的:
public interface IRtfDocument : IDocument
{
new IRtfParagraphs Paragraphs { get; }
new IRtfRevisions Revisions { get; }
new IRtfStyles Styles { get; }
string Rtf { get; }
}
Run Code Online (Sandbox Code Playgroud)
这被认为是好习惯吗?它似乎适合这种情况,但我想由你的C#退伍军人来管理它.
更新:所以我实际上继续尝试使用我的界面中描述的"新".我的RtfDocument类最终需要一个IDocument.Styles属性和一个IRtfDocument.Styles属性.虽然我可以让IDocument.Styles属性返回IRtfDocument.Styles的值,但由于我正在实现两个属性,因此感觉不太正确.
这似乎编译器不考虑该IRtfStyles从IStyles派生的事实,所以它坚持我兼得.如果Liskov Substitution Principle让我在RtfDocument类中实现IRtfDocument.Styles 会很好.
更简单的解决方案可能只是拥有一个通用接口:
public interface IFooBox<T>
where T : IFoo
{
T Foo { get; }
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以拥有IFooBox<IFoo>基本对象或IFooBox<IEnhancedFoo>增强版本.
您使用新修饰符存在很大的潜在问题。假设我们使用您的接口:
public interface IFoo
{
string Name { get; set; }
}
public interface IEnhancedFoo : IFoo
{
int BarCount { get; set; }
}
public interface IFooBox
{
IFoo Foo { get; set; }
}
public interface IEnhancedFooBox : IFooBox
{
new IEnhancedFoo Foo { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
建立我们的课程:
public class EnhancedFooBox : IEnhancedFooBox
{
public IEnhancedFoo Foo { get; set; }
IFoo IFooBox.Foo { get; set; }
}
public class FooBase : IFoo
{
public string Name { get; set; }
}
public class EnhancedFoo : IEnhancedFoo
{
public int BarCount { get; set; }
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
构建一些采用接口的方法...
static void Test1(IFooBox myBlah)
{
myBlah.Foo = new FooBase();
myBlah.Foo.Name = "FooBase";
}
static void Test2(IEnhancedFooBox myBlah)
{
myBlah.Foo = new EnhancedFoo();
myBlah.Foo.Name = "EnhancedFoo";
}
Run Code Online (Sandbox Code Playgroud)
然后使用这个逻辑:
static void Main(string[] args)
{
var myBlah = new EnhancedFooBox();
Test2(myBlah); //first assign name to EnhancedFoo
Test1(myBlah); //second assign name to FooBase
Console.Write(myBlah.Foo.Name);
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
什么是预期的输出?应该是 FooBase 还是EnhancedFoo?
增强型Foo
程序员不知道该属性已被修改为新的,将无法获得预期的输出。这是使用泛型解决的。
| 归档时间: |
|
| 查看次数: |
5084 次 |
| 最近记录: |