Абстрактный фабричный образец - PullRequest
2 голосов
/ 27 января 2011

У меня есть класс CMyDataClass для хранения данных, который имеет три переменные-члена и два конструктора, например

public class CMyDataClass
{
    public String strIndex, strName;
    public int nType;
    public CMyDataClass()
    {
        strIndex = "";
        strName = "";
        nType = 0;
    }
    public CMyDataClass(String ind, String name, int ty)
    {
        strIndex = ind;
        strName = name;
        nType = ty;
    }
}

А в другом классе (CMain) у меня есть List<CMyDataClass>, который содержит два объекта, таких как

 List<CMyDataClass> lstMyDataList = new List<CMyDataClass> { new CMyDataClass("", "", 1), 
                                                             new CMyDataClass("", "", 2) };

У меня есть два дочерних класса, которые наследуют CMyDataClass, и каждый из них содержит функцию для заполнения структуры данных.

Функция в дочернем классе заполнит объект на основе ntype.

Вот мои детские классы

//Class One

class COne : CMyDataClass
{
    public static bool FillData(CMyDataClass objCMDClass)
    {
        if (objCMDClass.nType == 1)
        {
            objCMDClass.strIndex = "Index-One";
            objCMDClass.strName = "One";
            return true;
        }
        return false;
    }
}



//Class Two

class CTwo : CMyDataClass
{
    public static bool FillData(CMyDataClass objCMDClass)
    {
        if (objCMDClass.nType == 2)
        {
            objCMDClass.strIndex = "Index-Two";
            objCMDClass.strName = "Two";
            return true;
        }
        return false;
    }
}

В классе CMain я выполняю функции дочернего класса, такие как

 public void Func()
    {
        for (int index = 0; index < lstMyDataList.Count; index++)
        {
            if (COne.FillData(lstMyDataList[index]) == false)
                if (CTwo.FillData(lstMyDataList[index]) == false)
                    MessageBox.Show("No data found");
        }
    }

Теперь проблема заключается в следующем: если COne или CTwo заполняет объект данных, он возвращает объект типа CMyDataClass. Но мне нужен объект дочернего класса, то есть, если COne заполняет объект, тогда объект должен иметь тип COne, или, если CTwo, тогда объект CTwo объект.

Так что я изменил свой Child класс как

class COne : CMyDataClass
  {
    public static bool FillData(CMyDataClass objCMDClass)
    {
        if (objCMDClass.nType == 1)
        {
            COne obj=new COne();
            obj.strIndex = "Index-One";
            obj.strName = "One";
            objCMDClass=obj
            return true;
        }
        return false;
    }
}

Но это не заполнит объект в lstMyDataList, потому что он создает новый объект.

Я могу использовать type cast, если мой CMyDataClass абстрактный. Но если я сделаю его абстрактным, я не смогу заполнить lstMyDataList следующим образом (тип объекта неизвестен).

 List<CMyDataClass> lstMyDataList = new List<CMyDataClass> { new CMyDataClass("", "", 1), new CMyDataClass("", "", 2) };

Как привести объект к типу child, в зависимости от того, какой класс заполняет объект?

Спасибо заранее.

Ответы [ 2 ]

5 голосов
/ 27 января 2011

Нельзя приводить объекты к дочернему типу, поскольку это не экземпляр дочернего типа.Вы не используете наследование, вы создаете экземпляры CMyDataClass и инициализируете их по-разному, в зависимости от параметра.

Трудно сказать, что именно вам нужно или нужно, и, учитывая это, этонеясно, нужно ли здесь наследование вообще.Но если вы хотите фабрику, это может быть что-то вроде этого:

    public class CMyDataClass
    {
        // ...snipped definition...
        public CMyDataClass(int type)
        {
            nType = type;
        }        

        public virtual void FillData()
        {
        }

        static public CMyDataClass Create(int type)
        {
            switch (type)
            {
                case 1:
                   return new COne(type);
                case 2:
                   return new CTwo(type);
                default:
                   return null // or throw an exception, whatever is appropriate
            }
        }
    }

    public class COne : CMyDataClass
    {
         public COne(int type)
             : base(type)
         {
         }

         public override void FillData()
         {
              strIndex = "Index-One";
              strName = "One";             
         } 
    }

    public class CTwo : CMyDataClass
    {
         public CTwo(int type)
             : base(type)
         {
         }

         public override void FillData()
         {
              strIndex = "Index-Two";
              strName = "Two";             
         } 
    }

//....
    List<CMyDataClass> lstMyDataList = new List<CMyDataClass> { CMyDataClass.Create(1), 
                                                                 CMyDataClass.Create(2) }
//....

//....
    public void Func()
    {
        for (int index = 0; index < lstMyDataList.Count; index++)
        {
            lstMyDataList[index].FillData();
        }
    }
//....
0 голосов
/ 27 января 2011

Как насчет упаковки CMyDataClass внутри другого класса и помещения экземпляров нового класса в список? Тогда вы можете иметь экземпляры COne или CTwo внутри в зависимости от того, какой метод был использован для его заполнения.

...