简体   繁体   English

我可以从基类内部将基类对象更改为派生类对象吗?

[英]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? 问题是,我无法在C#中解决this问题,那么我可以使用哪种替代方法?

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. 您应该分离出2个行为,并且可以使用Factory类根据您提供的数据创建特定类型的A

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? DoStuff方法移动到基类怎么样? 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 ): 您可以告诉班级做一些事情,而不是询问班级类型并根据这些信息做出决定,而是决定如何处理它的内部状态( Tell,Do not 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? 我是否正确理解您希望让特定类型根据您输入的数据而有所不同,但是您希望保留一些驻留在“A”基类中的状态,这样您就无法完全创建新对象了?

  • 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. 您可以使用一个工厂方法接受“A”的实例和一组数据作为参数,返回由数据决定的类型的新对象,但也包含传递的对象的状态。
  • 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. 你可以通过让AFirstType和ASecondType完全不相关来完成整个事情,但两者都有一个A实例的引用(没有任何一个来自它的实例)。
  • You should look into composition based patterns (like state and strategy). 您应该研究基于组合的模式(如状态和策略)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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