Thorin Oakenshield
Thorin Oakenshield

Reputation: 14672

Abstract factory pattern

I have a class, CMyDataClass, to store data, which has three member variables and two constructors like

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;
    }
}

And in another class (CMain) I've a List<CMyDataClass> which contains two objects like

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

I have two child classes which inherit the CMyDataClass and each contain a function to fill the data structure.

The function in the child class will fill the object based on the ntype.

Here are my child classes

//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;
    }
}

In the CMain class I execute the child class functions like

 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");
        }
    }

Now the problem is: if COne or CTwo fills the data object, it return an object of type CMyDataClass. But I need the object of the child class i.e, if COne fills the Object then the object should be of COne type, or if CTwo then the object should be CTwo object.

So I changed my Child class as

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;
    }
}

But this will not fill the object in the lstMyDataList, 'cause it creates a new object.

I can use type cast if my CMyDataClass is abstract. But if I make it as abstract I can't fill the lstMyDataList as follows( object type unknown ).

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

How to cast the object to child type,based on which class fills the object?

Thanks in advancce.

Upvotes: 2

Views: 525

Answers (2)

Willem van Rumpt
Willem van Rumpt

Reputation: 6570

You can't cast the objects to the child type, since it's not instance of the child type. You're not using inheritance, you're creating instances of CMyDataClass, and initialize them differently, depending on a parameter.

It's hard to tell what exactly you need or want, and, given that, it's unclear whether inheritance is needed here at all. But if it's a factory you want, it could be something like this:

    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();
        }
    }
//....

Upvotes: 5

Nils Magne Lunde
Nils Magne Lunde

Reputation: 1824

What about wrapping the CMyDataClass inside another class, and put instances of the new class inside the list box? Then you can have instances of either COne or CTwo inside depending on which method was used to fill it.

Upvotes: 0

Related Questions