Использование методов наследования с другой переменной (другого типа) - PullRequest
0 голосов
/ 03 сентября 2010

Я новичок в программировании с ООП, я пытаюсь правильно использовать концепцию наследования.

Вот код, который я попробовал ( Ссылка здесь )

public class Base
{
    //Type?
    public abstract static object Adapter();              

    public static DataTable GetWOCost(DateTime Date, string WO)
    {
        Application.UseWaitCursor = true;
        DataTable dt = new DataTable();

        try
        {
            //Cast?
            dt = Adapter().GetDataByWO(WO, Date);
            Application.UseWaitCursor = false;
            return dt;

        } catch (Exception)
        {
            return null;
        }
    }
} 

public class Materiel : Base
    {
        static AllieesDBTableAdapters.CoutMatTableAdapter Adapter()
        {
            return new AllieesDBTableAdapters.CoutMatTableAdapter();        
        }
    }

    public class Labor : Base
    {
        static AllieesDBTableAdapters.CoutLaborTableAdapter Adapter()
        {
            return new AllieesDBTableAdapters.CoutLaborTableAdapter();
        }
    }

Сначала весь мой код был в классе Material.Но затем мне пришлось добавить второй идентичный класс, но для другого адаптера SQL.Я пробовал разные вещи, но приведенный выше код имеет большую проблему.

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

Может быть, мне следует перейти на .NET 4.0 и использоватьдинамический объект?

edit: Также, похоже, есть проблема с абстрактным и статическим, поэтому я не могу использовать модификатор static в моем методе GetWOCost () без экземпляра Adapter () (в базовом классе),Кажется, было бы проще просто скопировать и вставить, но я пытаюсь найти правильный способ сделать это.

Ответы [ 2 ]

2 голосов
/ 03 сентября 2010

Что вы должны сделать в такой ситуации, так это запрограммировать интерфейс , который определяет контракт для того, что вы хотите сделать с объектом Adapter. Если ваши классы реализации не имеют общего интерфейса, вы можете создать его для них.

Затем вы можете создавать различные реализации этого интерфейса; и в каждом подклассе переопределите метод адаптера для возврата правильной реализации интерфейса.

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

В коде это может выглядеть так (упрощенно):

public interface IAdapter 
{
    DataTable GetWOCost();  // Implementors must have a method with this signature
}

public class Base 
{
    public abstract IAdapter Adapter();  

    // Methods that use IAdapter instances here.
}

class Materiel : Base 
{
    public override IAdapter Adapter() { return new CoutMatTableAdapter(); } 
}

class Labor : Base 
{
    public override IAdapter Adapter() { return new CoutLaborTableAdapter(); }
}

Тогда вам просто нужно, чтобы ваши новые адаптеры реализовали ваш новый интерфейс, например:

public class CoutLaborTableAdapter : IAdapter 
{
    public DataTable GetWOCost() { /* implementation */ }
}
0 голосов
/ 03 сентября 2010

ОК. Я сделал ваше решение работоспособным, возникла путаница с GetDataByWO & GetWOCost.Вы не использовали правильный.

    public interface IAdapter
{
    DataTable GetDataByWO(string WO, DateTime Date);   
}

public abstract class Base
{
    public abstract IAdapter Adapter(); 

    public DataTable GetWOCost(DateTime Date, string WO)
    {
        Application.UseWaitCursor = true;
        DataTable dt = new DataTable();

        try
        {
            dt = Adapter().GetDataByWO(WO, Date);
            Application.UseWaitCursor = false;
            return dt;

        } catch (Exception)
        {
           return null;
        }
    }
}

public class Materiel : Base
{
    public override IAdapter Adapter()
    {
        return new CoutMatTableAdapter();        
    }
}

public class Labor : Base
{
    public override IAdapter Adapter()
    {
        return new CoutLaborTableAdapter();
    }
}

public class CoutMatTableAdapter: IAdapter
{
    public DataTable GetDataByWO(string WO, DateTime Date)
    {
        AllieesDBTableAdapters.CoutMatTableAdapter adpt = new AllieesDBTableAdapters.CoutMatTableAdapter();
        return adpt.GetDataByWO(WO, Date);
    }
}

public class CoutLaborTableAdapter : IAdapter
{
    public DataTable GetDataByWO(string WO, DateTime Date)
    {
        AllieesDBTableAdapters.CoutLaborTableAdapter adpt = new AllieesDBTableAdapters.CoutLaborTableAdapter();
        return adpt.GetDataByWO(WO, Date);
    }
}

Теперь, чтобы выяснить, почему трудовой класс выдает исключение (сгенерированная часть SQL).Так что кажется, что Abstract и static не подходят друг к другу (я могу понять почему, но было бы здорово иметь статический метод)

...