абстрактный метод в виртуальном классе - PullRequest
4 голосов
/ 05 марта 2009

У меня есть класс c #, который имеет много виртуальных методов, некоторые из этих методов по существу абстрактны (они полностью реализованы в подклассах, а базовый класс пуст).

Чтобы получить его для компиляции, я бросаю InvalidOperationException в базовом классе с комментарием о том, что должно быть сделано. Это просто грязно.

Есть ли лучший способ создать мои классы?

редактирование: Именно для среднего уровня приложения, которое будет запущено в Канаде, половина методов являются общими, а следовательно - виртуальными. и половина методов зависит от провинции.

Public class PersonComponent() 
{

 public GetPersonById(Guid id) {
  //Code to get person - same for all provinces
 }

 Public virtual DeletePerson(Guid id) {
  //Common code
 }

 Public virtual UpdatePerson(Person p) {
  throw new InvalidOperation("I wanna be abstract");
 }

Public Class ABPersonComponent : PersonComponent
{
    public override DeletePerson(Guid id) 
    {
       //alberta specific delete code
    }

    public override UpdatePerson(Person p) 
    {
       //alberta specific update codecode
    }

}

надеюсь, что это имеет смысл

Ответы [ 2 ]

15 голосов
/ 05 марта 2009

Пометить базовый класс как абстрактный, а также методы, которые не имеют реализации.

Вот так

public abstract class BaseClass
{

    public abstract void AbstractMethod();
}

public class SubClass: BaseClass
{
    public override void AbstractMethod()
    {
        //Do Something
    }
}

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

Редактировать: Посмотрев на ваш класс, я бы сделал абстрактным PersonComponent вместе с методом UpdatePerson. Либо так, либо если UpdatePerson просто ничего не делает для PersonComponent, оставьте все как есть, но оставьте метод UpdatePerson пустым для PersonComponent.

1 голос
/ 05 марта 2009

Подумайте о вашей иерархии объектов. Вы хотите поделиться общим кодом для всех ваших производных классов, а затем реализовать базовую функциональность в базовом классе.

При наличии общего базового кода, обратите внимание на шаблон. Используйте публичный метод и связывайте его с защищенным виртуальным методом с помощью базовой / разделяемой реализации. Завершите разделяемое имя метода реализации "Core".

Например:

public abstract class BaseClass
{
    protected virtual void DeletePersonCore(Guid id)
    {
        //shared code
    }

    public void DeletePerson(Guid id)
    {
        //chain it to the core
        DeletePersonCore(id);
    }
}

public class DerivedClass : BaseClass
{
    protected override void DeletePersonCore(Guid id)
    {
        //do some polymorphistic stuff

        base.DeletePersonCore(id);
    }
}

public class UsageClass
{
    public void Delete()
    {
        DerivedClass dc = new DerivedClass();

        dc.DeletePerson(Guid.NewGuid());
    }
}
...