如何从派生类隐藏扩展方法?

4 c# inheritance extension-methods

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

public abstract class OptionalParameter
{
    //Template Method Pattern
    public string GenerateQueryString()
    {
        return this.GenerateQueryStringWithParameters();
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个所有OptionalParameter类型的扩展方法.

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

    }
}
Run Code Online (Sandbox Code Playgroud)

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

public class CalendarEventParameters : OptionalParameter
{

}
Run Code Online (Sandbox Code Playgroud)

当我想创建一个实例时,CalenderEventParameter我GenerateQueryString()在抽象类和GenerateQueryStringWithParameters()扩展方法中看到了这两个方法.

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

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

Pat*_*man 5

不能.扩展方法通常不能从派生类中隐藏.

只有当另一个类在扩展方法的所有调用者之外的另一个程序集中时才可能(那么你可以标记扩展方法internal).

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


The*_*aot 2

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

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

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

但老实说,这不是 OOP 应该如何工作的,去重新考虑你的设计吧。


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

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


看看你的模式 - 请参阅代码中的注释:

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

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

public abstract class OptionalParameter
{
    public virtual string GenerateQueryString()
    {
        // Default implementation, whatever
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以替换实现:

public class CalendarEventParameters : OptionalParameter
{
    public override string GenerateQueryString()
    {
        // Custom implementation
    }
}
Run Code Online (Sandbox Code Playgroud)