performing a child classes method when called as a

2019-09-05 04:06发布

问题:

I have a class Class A, and a class Class B. class B is a child of class A so that:

public class Class A
{
   public DateTime FileStart
   {
      get
      {
          return Header.StartTime;
      }
      set{ }
   }
   ...
   ...
}

and

public class B : A
{
   FileInfo zippedA;
   public A myA = null;
   internal B(FileInfo mFileInfo)
   {
      ...
      //collects the same data as A from the fileinfo such as  start time...
      ...
   }
   public A getAData()
   {
      UnZipFile(zippedA);
      return myA;
   }
   ...
}

So I'm looking for a way to call getAData() whenever an object of B is called as A for example the list Xlist stores all As and Bs but will be accessed from several places in the code:

   SortedList Xlist = new SortedList();
   public void GetFrames(DateTime desiredStartTime, DateTime  desiredEndTime)
   {
       for(int fileIdx = Xlist.Values.Count-1; fileIdx >= 0; --fileIdx)
       {
           //my hope is that there is a way to set up B in it's class to say
           // "if I get called as an A, I'll perform getAData() and return myA instead.
           A rec = (A)Xlist.GetByIndex(fileIdx);
           ...
           ...
       }
   }

in the above instance I would like for every time an object is pulled from Xlist if its a B but gets caste as an A like so, it automatically calls the getAData() function and returns the resulting A instead of its self. is this possible??

回答1:

You can make the method in parent class virtual and override it in the child classes. In doing so anywhere you call the method on an instance of type A, it will invoke the method in the derived type if the derived type provides and override, otherwise it will invoke the version in type A.

This is the simplest way, the alternative aren't very attractive. For more information on virtual methods in C# check out this msdn article; http://msdn.microsoft.com/en-us/library/aa645767(v=vs.71).aspx

To do what you think you want to do (I'm pretty sure it's not actually what you want to do) you can do this;

   for(int fileIdx = Xlist.Values.Count-1; fileIdx >= 0; --fileIdx)
   {
       A rec = (A)Xlist.GetByIndex(fileIdx);
       if (rec.GetType() == typeof(B))
       {
            B temp = (B) rec;
            rec = temp.getAData();
       }
   } 

Although, again, this makes no sense at all. Here's an example;

public class Car
{
     int year;
     bool manual;
}

public class Porsche : Car
{
    bool specialPorscheOnlyFeature;
    Engine enginge;
}

public class Engine
{
   string engineType;
} 
// in some method

Porsche p = new Porsche();
// to get Car data
int yearOfCar = p.year; 
bool isManual = p.manual;
bool specialFeature = p.SpecialPorscheOnlyFeature;

Above is an example of how inheritance works. I don't retrieve an instance of the base class, everything the base class has is baked into the instance of the derived class. You're acting like the base class is some other object the derived class is composed of.



回答2:

It may not be the best way to do it, but would this not work?

class File
{
    public string FileInfo = "";

    public override string ToString()
    {
        return FileInfo;
    }

    public virtual File GetRaw()
    {
        return this;
    }
}

class ZippedFile : File
{
    public File Unzip()
    {
        // Do actual unzip here..
        return new File { FileInfo = FileInfo.Substring(0,8) };
    }

    public override File GetRaw()
    {
        return Unzip();
    }
}

class Program
{
    static void Main(string[] args)
    {
        List<object> files = new List<object>();

        files.Add(new File { FileInfo = "BeepBoop" });
        files.Add(new ZippedFile { FileInfo = "BeepBoopfQAWEFRLQER:LKAR:LWEasdfw;lekfrqW:ELR" });
        files.Add(new File { FileInfo = "BoopBeep" });
        files.Add(new ZippedFile { FileInfo = "BoopBeepAWSLF:KQWE:LRKsdf;lKWEFL:KQwefkla;sdfkqwe" });

        foreach(var f in files)
        {
            File rawFile = ((File)f).GetRaw();
            Console.WriteLine(rawFile);
        }

        Console.ReadKey();
    }
}