简体   繁体   English

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

[英]How to hide extension methods from derived classes?

I have a base abstract class to implement template method pattern. 我有一个基本抽象类来实现模板方法模式。

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

And I have an extension method for all OptionalParameter type. 我有一个所有OptionalParameter类型的扩展方法。

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

    }
}

I inherited a class from OptionalParameter named CalendarEventParameter. 我从OptionalParameter继承了一个名为CalendarEventParameter的类。

public class CalendarEventParameters : OptionalParameter
{

}

When I want to create an instance of CalenderEventParameter I see both GenerateQueryString() method in abstract class and GenerateQueryStringWithParameters() extension method. 当我想创建CalenderEventParameter的实例时,我在抽象类和GenerateQueryStringWithParameters()扩展方法中都看到了GenerateQueryString()方法。

I don't wan to see it from derived classes. 我不想从派生类中看到它。 I tried to sign extension method as Private but this way I cannot access also from my abstract class. 我试图将扩展方法签名为Private,但这样我也无法从我的抽象类访问。

Is it possible to able to call extension method only from base abstract class? 是否可以仅从基本抽象类调用扩展方法?

No. Extension methods generally can't be hidden from derived classes. 不能。扩展方法通常不能从派生类中隐藏。

It is only possible when the other class is inside another assembly than all the callers of the extension method (you could mark the extension method internal then). 只有当另一个类在扩展方法的所有调用者之外的另一个组件内时才可能(您可以将扩展方法标记为internal )。

You could also put the extension method inside another namespace, which you include in every class file you want to call the extension method on. 您还可以将扩展方法放在另一个名称空间中,该名称空间包含在要调用扩展方法的每个类文件中。 This isn't true hiding, but it might do the job. 这不是真正的隐藏,但它可能会起作用。

First off, if you want an extension method only for a class, and you have control of that class. 首先,如果您只想要一个类的扩展方法,并且您可以控制该类。 You can make that method member of the class. 您可以使该方法成为该类的成员。 Second you want a method to exist on a class but on its derived classes? 第二,你想要一个方法存在于一个类,但在其派生类上? That's not how it is supposed to work. 这不是它应该如何工作。

Try making that method internal, so you have total control on where it gets called. 尝试将该方法设为内部,这样您就可以完全控制调用它的位置。 If you need it to be public, you can have it belong to an interface, and use an implicit implementation, that way it will only be available if you cast the object. 如果你需要它是公共的,你可以让它属于一个接口,并使用一个隐式实现,这样只有在你强制转换对象时它才可用。

You may also consider to hide the member from intellisense, or making it obsolete... 您也可以考虑隐藏智能感知中的成员,或者使其过时...

But in all honesty, that is not how OOP should work, go rethink your design. 但老实说,OOP不应该如何工作,重新考虑你的设计。


It may be worth noting that if you have an extension method with the same name and signature than an actual method, the actual method takes preference. 值得注意的是,如果您的扩展方法具有与实际方法相同的名称和签名,则实际方法会优先考虑。 So you can have the extension method for the base class, and add an actual method in the derived classes... 所以你可以拥有基类的扩展方法,并在派生类中添加一个实际的方法......

If you are doing that, why don't yuu just have a method and make it virtual. 如果你这样做,为什么yuu只有一个方法并使其成为虚拟。 So the derived class can replace the implementation. 因此派生类可以替换实现。


Look at your pattern - see comments in code: 查看您的模式 - 请参阅代码中的注释:

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

That means that the extension method IS the default implementation. 这意味着扩展方法是默认实现。 Just make that method virtual: 只需将该方法设为虚拟:

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

And then, you can replace the implementation: 然后,您可以替换实现:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM