猿问

基于界面的强制输入

我有一个抽象类,它强制实现一个方法,该方法将接口作为输入,如下所示:


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用作输入,因为那时我将无法访问自定义属性。


如何解决这个问题?这让我很头疼...


偶然的你
浏览 152回答 3
3回答

POPMUISE

您当前的抽象类要求该方法接受任何实现IDocumentArgs. 您可以或许检查,当它在真实传递的类型,但是编译器本身不会强制执行它。您可以做的一件事是将抽象类更改为泛型。像这样的东西:public abstract class DocumentWriter<T> where T : IDocumentArgs{&nbsp; &nbsp; protected abstract void FillContent(T args);}请注意where对类型参数的约束,要求实现类型仅使用 的派生IDocumentArgs作为类型参数。然后在实现该类时,明确提供类型参数:public class ActualDocumentWriter : DocumentWriter<ActualDocumentArgs>{&nbsp;&nbsp; &nbsp; protected override void FillContent(ActualDocumentArgs args)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // Do stuff&nbsp; &nbsp; }}

汪汪一只猫

您可以使用通用约束:public abstract DocumentWriter<T>&nbsp; where T : IDocumentArgs{&nbsp; &nbsp; (...)&nbsp; &nbsp; protected abstract void FillContent(T args);}public class ActualDocumentWriter : DocumentWriter<ActualDocumentArgs>{&nbsp; &nbsp; (...)&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; protected override void FillContent(ActualDocumentArgs args)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // Do stuff&nbsp; &nbsp; }}

PIPIONE

我不能使用 IDocumentArgs 作为输入,因为那时我将无法访问自定义属性。是设计错误的指示。你不应该想要那个。您可以绕过它,在覆盖方法中,您可以对其进行类型转换:protected override void FillContent(IDocumentArgs args){&nbsp; &nbsp; var actualArgs = args as ActualDocumentArgs ;&nbsp; &nbsp; // Do stuff}但这是一个黑客。
随时随地看视频慕课网APP
我要回答