简体   繁体   中英

Can I change a base class object to a derived class object from inside the base class?

Basically, I want to do something like this:

public class A
{
    public void AddData(byte[] Data)
    {
        //analyze data
        if (BoolFromAnalyzedData == true)
        {
            AFirstType a = new AFirstType();
            a.SomeInt = IntFromAnalyzedData;
            this = a;
        }
        else
        {
            ASecondType a = new ASecondType();
            a.SomeString = StringFromAnalyzedData;
            this = a;
        }
    }
}
public class AFirstType : A
{
    public int SomeInt;
}
public class ASecondType : A
{
    public string SomeString;
}

Then, I want to be able to do this:

a.AddData(data);
if (a is AFirstType)
    DoStuff((a as AFirstType).SomeInt);
else if (a is ASecondType)
    DoStuff((a as ASecondType).SomeString);

I have a class and then two derived classes with different properties. When I create the base class I have no idea which type it should be, I can only understand which type it is late when I get some data and analyze it. Then, I want to be able to check which type it is and use the derived class' properties.

Problem is, I can't assing this in C#, so what alternative way can I use?

Once you instantiate the class as a particular type, you can't change that type, at least not as far as I know.

My suggestion would be simply to not instantiate it until you know what type it will be.


Maybe you're looking for this pattern(notice how it creates and returns a class instead of changes the class)

public static A AddData(byte[] Data)
{
    //analyze data
    if (BoolFromAnalyzedData == true)
    {
        AFirstType a = new AFirstType();
        a.SomeInt = IntFromAnalyzedData;
        return a;
    }
    else
    {
        ASecondType a = new ASecondType();
        a.SomeString = StringFromAnalyzedData;
        return a;
    }
}

you can then invoke it by

A a = AddData(mydata);

You can also design your base class such that it can do everything that your proposed derived classes do anyway. It all depends on your requirement.

I think you should change your approach to the problem.

Your mixing up your Entity's (which store the data) with your Hydration Code (which populates them).

You should seperate out the 2 behaviors and maybe use a Factory Class to create a specific type of A based on the data that you provide.

public class A 
{ 
   //Common Stuff
}

public class AFirstType : A
{
    public int SomeInt {get;set;}
}
public class ASecondType : A
{
    public string SomeString {get;set;}
}

public class AFactory 
{
    public static void Create(byte[] Data)
    {
        //analyze data
        if (BoolFromAnalyzedData == true)
        {
            return new AFirstType() 
                       {
                           SomeInt = IntFromAnalyzedData
                       };
        }
        else
        {
            return new  ASecondType() 
                        {
                           SomeString = StringFromAnalyzedData
                        };
        }
    }
}

///Main Code

byte [] data = GetData();
A someA = AFactory.Create(data);
if (a is AFirstType)
    DoStuff((a as AFirstType).SomeInt);
else if (a is ASecondType)
    DoStuff((a as ASecondType).SomeString);

What about moving DoStuff method into base class? Instead of asking about class type and making decisions based on that information you can just tell class to do some stuff, and it will decide what to do on it's internal state ( Tell, Don't Ask ):

public class A
{
    public void AddData(byte[] Data)
    {
        // add data    
    }

    public void DoStuff()
    {
        if (BoolFromAnalyzedData)
        {
            int value = IntFromAnalyzedData;
            // do stuff with value
        }
        else
        {
            string value = StringFromAnalyzedData;
            // do other stuff
        }
    }
}

Actually you don't need any child classes in this case. And your code will look like:

a.AddData(data);
a.DoStuff();

Do I understand you correctly that you want to let the specific type vary in accordance with the data you shove into it, but you wish to preserve some state that reside in "A" base class so you cannot create a new object entirely?

  • You can have a factory method that accepts an instance of "A" and a set of data as parameters, returning a new object of a type decided by the data, but which also contains the state of the passed object.
  • You can turn the whole thing on its head by having AFirstType and ASecondType being totally unrelated, but both having a reference to an instance of A (without any of them deriving from it.
  • You should look into composition based patterns (like state and strategy).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM