【问题标题】:How to hide extension methods from derived classes?如何隐藏派生类的扩展方法?
【发布时间】:2015-08-03 13:35:39
【问题描述】:

我有一个基本抽象类来实现模板方法模式。

public abstract class OptionalParameter
{
    //Template Method Pattern
    public string GenerateQueryString()
    {
        return this.GenerateQueryStringWithParameters();
    }
}

而且我有一个适用于所有 OptionalParameter 类型的扩展方法。

public static class OptionalParameterExtensions
{
    public static string GenerateQueryStringWithParameters(this OptionalParameter optionalParameters)
    {

    }
}

我从 OptionalParameter 继承了一个名为 CalendarEventParameter 的类。

public class CalendarEventParameters : OptionalParameter
{

}

当我想创建CalenderEventParameter 的实例时,我在抽象类中看到GenerateQueryString() 方法和GenerateQueryStringWithParameters() 扩展方法。

我不想从派生类中看到它。我试图将扩展方法签名为私有,但这样我也无法从我的抽象类访问。

是否可以只从基抽象类调用扩展方法?

【问题讨论】:

  • 为什么要隐藏扩展方法?或者更确切地说,您为什么首先将其声明为扩展方法?
  • 扩展方法是编译器的东西。 Intellisense 使用 type 来确定它何时适用。由于继承,任何继承的类型都将显示其基类型扩展方法。从理论上讲,只要扩展名从列表中隐藏,就可以通过一些 VS 扩展名来定义(通过某些属性)来隐藏它。另请参阅this 问题,特别是 Jon 的想法(为扩展方法提供单独的命名空间)。

标签: c# inheritance extension-methods


【解决方案1】:

没有。扩展方法通常不能从派生类中隐藏。

只有当其他类在另一个程序集中而不是扩展方法的所有调用者时才有可能(然后您可以标记扩展方法internal)。

您还可以将扩展方法放在另一个命名空间中,您可以将其包含在要调用扩展方法的每个类文件中。这不是真正的隐藏,但它可能会起到作用。

【讨论】:

    【解决方案2】:

    首先,如果您只想要一个类的扩展方法,并且您可以控制该类。您可以使该方法成为该类的成员。 其次,您希望方法存在于类上但存在于其派生类上?这不是它应该的工作方式。

    尝试使该方法成为内部方法,这样您就可以完全控制调用它的位置。如果你需要它是公共的,你可以让它属于一个接口,并使用一个隐式实现,这样它只有在你转换对象时才可用。

    您也可以考虑从智能感知中隐藏该成员,或使其过时...

    但老实说,这不是 OOP 的工作方式,请重新考虑您的设计。


    值得注意的是,如果您有一个与实际方法具有相同名称和签名的扩展方法,则实际方法优先。所以你可以拥有基类的扩展方法,并在派生类中添加一个实际的方法......

    如果你正在这样做,你为什么不只是有一个方法并将其虚拟化。所以派生类可以代替实现。


    看看你的模式 - 查看代码中的 cmets:

    public abstract class OptionalParameter
    {
        public string GenerateQueryString()
        {
            // You are calling the extension method here
            return this.GenerateQueryStringWithParameters();
        }
    }
    

    这意味着扩展方法是默认实现。只需将该方法设为虚拟:

    public abstract class OptionalParameter
    {
        public virtual string GenerateQueryString()
        {
            // Default implementation, whatever
        }
    }
    

    然后,您可以替换实现:

    public class CalendarEventParameters : OptionalParameter
    {
        public override string GenerateQueryString()
        {
            // Custom implementation
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多