Проблема с частичным методом C # 3.0 - PullRequest
2 голосов
/ 10 апреля 2009

Знаете ли вы ответ на следующий вопрос?

Допустим, объявлен MyMethod () как частичный метод в MyPartialClass в MyPartialClass.cs. У меня также предоставленное тело MyMethod () в MyPartialClass в MyPartialClass2.cs. Я использую проблему без ответа «Магия» генератор кода, который на самом деле имеет сгенерированный MyPartialClass.cs, давайте скажем, на основе некоторой схемы БД. Немного невинный парень меняет схему навсегда а затем запускает «Магию». MyPartialClass.cs воссоздан, но с MyMethod2 () вместо MyMethod () декларация. Подумай обо мне. я думая, что я реализовал MyMethod (), который используется «Магией» но на самом деле «Магия» использует MyMethod2 (). C # компилятор не говорит мне, что у меня есть частичный метод реализовано без какой-либо декларации и моя реализация не используется в все!

Любое решение?

Я думаю, что это проблема без ответа.

РЕДАКТИРОВАТЬ Я получил ответ :-). В моем коде была опечатка, и поэтому компилятор не отмечал ошибку. Джон уже указал на это.

Ответы [ 3 ]

6 голосов
/ 10 апреля 2009

Вы должны получить ошибку CS0759. Контрольный пример:

partial class MyClass
{
    partial void MyMethod()
    {
        Console.WriteLine("Ow");
    }
}

partial class MyClass
{
    partial void MyMethod2();
}

Результаты компиляции:

Test.cs(6,18): error CS0759: No defining declaration found for implementing 
declaration of partial method 'MyClass.MyMethod()'

Разве это не делает то, что вы хотите?

2 голосов
/ 10 апреля 2009

Короче, нет; в этом суть частичных методов - декларирующему коду не нужно знать, предоставляется ли реализация или нет.

Конечно, вы можете просто не объявлять частичный метод: потреблять его , предполагая, он существует; если вы не предоставите его, компилятор пожалуется на отсутствующий метод.

Существует хакерский способ проверки во время выполнения (с использованием partial методов), который заключается в том, чтобы другая половина обновляла переменную ref:

partial void Foo(ref chk);

partial void Foo(ref chk) { chk++;}

(и убедитесь, что он изменяется) - но в целом частичные методы предназначены для того, чтобы не знать, вызваны ли они.

Другим подходом является базовый класс с методом abstract - тогда компилятор принудительно его реализует.

1 голос
/ 10 апреля 2009

В этом вся цель частичных методов. Если метод не реализован, он удаляется без трассировки и без предупреждения.

Одним из решений проблемы такого типа было бы использование шаблона с двойным производным в генерации кода. Это широко используется DSLTools и является довольно мощным.

Введите следующий код от руки:

public class MyClassBase
{
    public abstract void MyMethod();
    //Put all other methods required by the class here.
}

public partial class MyClass : MyClassBase
{
   //This class is entirely empty! 
}

Сгенерируйте следующий магический код.

public partial class MyClass
{
    public void MyMethod(){}
}

Если кто-то не сможет внедрить MyMythod () в сгенерированный код, вы получите ошибку компилятора.

...