Как расширить метод с тем же именем и получить вызов? - PullRequest
1 голос
/ 01 декабря 2011

Мне нравится переписывать метод в классе, поэтому я расширяю метод с тем же именем и параметром, но он никогда не вызывается.

http://msdn.microsoft.com/en-us/library/bb383977.aspx

.... Метод расширения с тем же именем и сигнатурой, что и у интерфейса или метода класса, никогда не будет вызываться. ....

Хорошо, я должен принять это.

Мой вопрос: для открытого класса (и даже у меня есть исходный код), если мне нравится переписывать метод OUTSide класса (в другом проекте, но в том же решении), как?

[EDIT]

Вот предложенный способ, используйте virtual / override, без ошибок во время выполнения, без ошибок при компиляции, просто никогда не вызывайте тоже :(, пожалуйста, посмотрите

В проекте A:

public class CachePlan : ICachePlan
{
    public virtual CacheSettings GetPlan(ControllerContext filterContext)
    {
        return null;
    }
}

В проекте B:

public class CachePlanExtension: CachePlan
{
    public override CacheSettings GetPlan(ControllerContext filterContext)
    {
        CacheSettings ca = new CacheSettings();
        ca.IsCachingEnabled = true;
        ca.Duration = 100;
        return ca;
    }
}

Но никогда не вызывать, CashPlan.GetPlan по-прежнему возвращает ноль. Anyidea

Ответы [ 6 ]

3 голосов
/ 01 декабря 2011

Вы не можете "добраться до" существующего класса и изменить значение его методов.Это было бы серьезной дырой в безопасности.

1 голос
/ 01 декабря 2011

Вы можете создать такой метод расширения (обратите внимание на ключевое слово this в списке параметров GetPlan ()):

public class CachePlanExtension //does not have to be static
{
    public static CacheSettings GetPlan(this CachePlan cachePlan, ControllerContext filterContext) //has to be static!
    {
        //the cachePlan-Parameter will later contain the CachePlan-object, on which you call this method. Example:
        var name = cachePlan.Name;


        CacheSettings ca = new CacheSettings();
        ca.IsCachingEnabled = true;
        ca.Duration = 100;
        return ca;
    }
}

Всякий раз, когда вы можете «видеть» класс расширения (это означает, что он долженбыть публичным или внутренним, и вы должны включить пространство имен класса расширения), вы можете вызвать метод следующим образом:

new CachePlan().GetPlan(filterContext);
1 голос
/ 01 декабря 2011

Методы расширения - это просто синтетический сахар, который компилируется в вызовы статических методов. Таким образом, вы можете просто написать статический метод, который выполняет то же самое, вы просто не сможете назвать его так, как вам нравится. Если метод виртуальный, вы можете переопределить его в производном классе. Просто убедитесь, что вы всегда создаете свой собственный тип. Вы также можете использовать ключевое слово new, но простое приведение и ваш код не будут использоваться. Лучше всего было бы создать простой класс-обертку для себя. Этот класс будет иметь экземпляр рассматриваемого класса и выяснить правильные вызовы. Это очень распространено при создании специальных коллекций, поскольку многие типы коллекций .NET не очень хорошо поддаются наследованию. Но хуже всего то, что вы могли бы использовать родинок .

Редактировать

Создайте свой собственный класс, который наследуется от ActionFilterAttribute, и используйте его для создания собственных пользовательских фильтров.

public class MyFilterAttribute : ActionFilterAttribute
{
    public override virtual void OnResultExecuting(ResultExecutingContext filterContext)
    {
        //...
    }
}

Переопределять это во встроенных атрибутах не рекомендуется, но вы можете подключиться к этому методу множеством других способов. Но если вы действительно хотите это сделать, MVC с открытым исходным кодом ...

1 голос
/ 01 декабря 2011

Если у вас есть исходный код, почему бы просто не удалить реализацию метода из исходного класса и предоставить метод расширения в отдельном проекте

1 голос
/ 01 декабря 2011

Проще говоря;"невозможно".Как объяснено на странице ...

Вы можете использовать методы расширения для расширения класса или интерфейса, но не для их переопределения.Метод расширения с тем же именем и сигнатурой, что и у интерфейса или метода класса, никогда не будет вызываться.Во время компиляции методы расширения всегда имеют более низкий приоритет, чем методы экземпляра, определенные в самом типе.Другими словами, если у типа есть метод с именем Process (int i) и у вас есть метод расширения с той же сигнатурой, компилятор всегда будет привязываться к методу экземпляра.Когда компилятор встречает вызов метода, он сначала ищет совпадение в методах экземпляра типа.Если совпадений не найдено, он будет искать любые методы расширения, определенные для этого типа, и связываться с первым найденным методом расширения.

0 голосов
/ 01 декабря 2011

Вы можете переопределить метод в унаследованном классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...