我有一个抽象类,它强制实现方法,该方法将接口作为输入,如下所示:
public abstract DocumentWriter
{
(...)
protected abstract void FillContent(IDocumentArgs args);
}
创建接口IDocumentArgs
是为了确保某些参数包含在参数中,否则该接口很大程度上取决于DocumentWriter
的实现。
public interface IDocumentArgs
{
string Title { get; set; }
string Subject { get; set; }
string Author { get; set; }
}
基于此接口,我实现了此接口的实现,该接口将在DocumentWriter
的实现中使用。看起来像这样:
public class ActualDocumentArgs : IDocumentArgs
{
// Properties enforced by the interface
string Title { get; set; }
string Subject { get; set; }
string Author { get; set; }
// Custom properties
string CustomerName { get; set; }
DateTime DueDate { get; set; }
(...)
}
问题是:我想使用FillContent()
实现ActualDocumentArgs
(我想应该可以实现,因为它实现了IDocumentArgs
),就像这样:
public class ActualDocumentWriter : DocumentWriter
{
(...)
protected override void FillContent(ActualDocumentArgs args)
{
// Do stuff
}
}
但是,如果执行此操作,则会出现编译时错误:
'ActualDocumentWriter.FillContent(ActualDocumentArgs)':找不到合适的方法来覆盖。
另一方面,我不能使用IDocumentArgs
作为输入,因为那样我将无法访问自定义属性。
如何解决这个问题?这让我头疼...
答案 0 :(得分:1)
您可以使用generic constraint:
public abstract DocumentWriter<T>
where T : IDocumentArgs
{
(...)
protected abstract void FillContent(T args);
}
public class ActualDocumentWriter : DocumentWriter<ActualDocumentArgs>
{
(...)
protected override void FillContent(ActualDocumentArgs args)
{
// Do stuff
}
}
答案 1 :(得分:1)
您当前的抽象类要求该方法接受实现IDocumentArgs
的所有内容。您可以 检查传入的类型,但是编译器本身不会强制执行。
您可以做的一件事是将抽象类更改为通用类。像这样:
public abstract class DocumentWriter<T> where T : IDocumentArgs
{
protected abstract void FillContent(T args);
}
请注意类型参数上的where
约束,要求实现类型仅将IDocumentArgs
的派生类型用作类型参数。
然后在实现该类时,显式提供type参数:
public class ActualDocumentWriter : DocumentWriter<ActualDocumentArgs>
{
protected override void FillContent(ActualDocumentArgs args)
{
// Do stuff
}
}
答案 2 :(得分:-1)
我不能使用IDocumentArgs作为输入,因为那样我将无法访问自定义属性。
表示设计错误。 你不应该这样。
您可以规避它,在覆盖方法内可以强制转换它:
protected override void FillContent(IDocumentArgs args)
{
var actualArgs = args as ActualDocumentArgs ;
// Do stuff
}
但这是黑客。