如何隐藏方法,以便程序员不会调用它,但仍然可以在代码中使用?

时间:2008-11-07 16:36:19

标签: c# inheritance

我有一个名为Ship的班级和一个名为Lifeboat

的班级

救生艇继承自Ship。

Ship包含一个名为Validate()的方法,该方法在保存之前调用,它有一个名为FurtherValidate()的抽象方法,它从Validate调用。这样做的原因是当你在基础上调用validate时它也验证了继承的类。所以我们有

public class Ship

public bool Validate()
{
    //validate properties only found on a ship

    FurtherValidate();
}

public abstract bool FurtherValidate();

所以Lifeboat

public override bool FurtherValidate()
{
    //validate properties only found on a lifeboat
}

这意味着任何实现Ship的人都需要为他们的类提供自己的验证,并且保证在save作为基础船时调用它。调用Validate(),然后调用继承的验证。

我们如何重新开始工作,所以我们仍然强制继承的类实现FurtherValidate(),但程序员永远不能调用FurtherValidate()。目前你可以调用Lifeboat.FurtherValidate(),我想以某种方式阻止这种情况。

9 个答案:

答案 0 :(得分:7)

protected abstract bool FurtherValidate();

只有船和救生艇现在可以看到它。

编辑: 救生艇必须能够看到它。当它甚至看不到它时,它应该如何覆盖FurtherValidate。我会将它重命名为ValidateCore,'核心'部分(对我而言)暗示不应该在没有充分理由的情况下调用它。

我认为将其抽象但不可见是不容易的。你需要对救生艇有一些信心;)

答案 1 :(得分:7)

简短的回答是,您无法从派生它的类隐藏派生方法。但是,您可以重构代码以完成您要实现的目标:

public class Ship
{    
    public virtual bool Validate()    
    {        
        //validate properties only found on a ship
        return true;
    }
}
public class Lifeboat : Ship
{   
    public override bool Validate()   
    {       
        base.Validate();       
        // lifeboat specific code
        return true;
    }
}

答案 2 :(得分:4)

您描述的确切方案是不可能的。您可以使用FurtherValidate访问修饰符将protected方法的访问权限限制为仅派生类。您还可以使用internal修饰符将其限制为仅在同一程序集中的类,但这仍然允许编写派生类的程序员随时调用FurtherValidate。使用protected和internal两者结合起来,实际上意味着仅限于在同一程序集中定义的派生类或类。

使用[EditorBrowsable]属性是一种IDE技巧,它将隐藏IntelliSense中的方法(除非其他程序员在VS中打开了正确的选项)。这将有效地阻止大多数人调用它(如果他们看不到它,它就不存在)。

您可以使用反射来询问您的来电者是谁,但我认为与此相比,这样做的性能成本太高了。

答案 3 :(得分:3)

最简单的答案是使方法受到保护。这允许继承者调用它但不公开它。但是,没有什么可以阻止继承类将方法更改为public。

我更倾向于完全删除FurtherValidate方法并让任何继承类覆盖Validate,如果愿意,可以调用base.Validate()。这允许任何从ship继承的类对validate方法有更大程度的控制。

答案 4 :(得分:2)

受保护是这里的正确方法。但在另一种情况下,您可能希望使用editorbrowsableattribute来隐藏intellisense中的方法。你仍然可以调用它,但它会减慢开发人员调用可能会破坏程序的速度,并且通常会强迫他们阅读你的巨大评论警告。

答案 5 :(得分:1)

使其受保护而不是公开将至少阻止外部对象调用它。

答案 6 :(得分:1)

我在这里看到代码味道,因为Validate不是船舶功能责任的一部分。换句话说,我想也许你正试图用继承来解决问题,这可能不是最好的解决方案。尝试重构验证逻辑,以便将验证注入到类中。这将更好地理解域对象Ship,因为船只不验证自己,它们在外部进行验证。如果要强制必须是验证器,那么如果属性为null,则可以抛出异常。

protected IValidator FurtherValidation { private get; set; }

public bool Validate()
{
//validate properties only found on a ship

    if (FurtherValidation == null)
        throw new ValidationIsRequiredException();
    if (!FurtherValidation.IsValid(this))
        // logic for invalid state
}

答案 7 :(得分:0)

您可以将方法标记为protected,这样只有继承类才能访问它。这并不妨碍继承者通过另一种公共方法暴露该方法,但这通常不是主要问题。

答案 8 :(得分:-1)

可能你可以试试私人修饰符