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

时间:2013-06-21 16:24:53

标签: c# oop

基本上,我想做这样的事情:

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

然后,我希望能够做到这一点:

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

我有一个类,然后是两个具有不同属性的派生类。当我创建基类时,我不知道它应该是哪种类型,我只能理解当我得到一些数据并对其进行分析时它是哪种类型。然后,我希望能够检查它是哪种类型并使用派生类的属性。

问题是,我无法在C#中使用this,所以我可以使用哪种替代方式?

4 个答案:

答案 0 :(得分:1)

将类实例化为特定类型后,您无法更改该类型,至少不是我所知道的。

我的建议只是在你知道它将是什么类型之前不要实例化它。


也许你正在寻找这种模式(注意它是如何创建并返回一个类而不是改变类)

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

然后你可以通过

调用它
A a = AddData(mydata);

您还可以设计基类,以便它可以执行您提议的派生类所做的所有操作。这一切都取决于你的要求。

答案 1 :(得分:1)

我认为你应该改变解决问题的方法。

您将实体(存储数据)与您的水合代码(填充它们)混合在一起。

您应该分离出2个行为,并可能使用工厂类根据您提供的数据创建特定类型的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);

答案 2 :(得分:0)

DoStuff方法移动到基类怎么样?您可以告诉班级做一些事情而不是询问班级类型并根据这些信息做出决定,而是决定如何处理内部状态(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
        }
    }
}

实际上,在这种情况下,您不需要任何子类。你的代码看起来像:

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

答案 3 :(得分:0)

我是否正确理解您希望让特定类型根据您输入的数据而有所不同,但您希望保留一些驻留在“A”基类中的状态,这样您就无法完全创建新对象?

  • 您可以使用一个工厂方法接受“A”实例和一组数据作为参数,返回由数据决定的类型的新对象,但也包含传递对象的状态。
  • 你可以通过让AFirstType和ASecondType完全不相关来改变整个事情,但两者都有一个A实例的引用(没有任何一个来自它。
  • 您应该研究基于构图的模式(如州和战略)。