区分两个班级

时间:2013-07-01 19:42:23

标签: c# visual-studio-2010 casting zip sortedlist

我有一个类FileRecord和一个类public class ZippedFileRecord : FileRecord,它存储在SortedList mFiles中,其中包含所有FileRecords和ZippedFileRecords。我遇到的问题是我需要一种方法来区分这两者,每个ZippedFileRecord都有一个FileRecord和一个名为GetFileRecord()的方法,它解压缩与ZippedFileRecord相关的文件并为它创建一个FileRecord(如下所示)下面的块...)

    public class ZippedFileRecord : FileRecord
    {
        FileInfo zipFileInfo; //FileName, FileCreationTime/Date
        public FileRecord myRecord = null;
        public FileRecord GetFileRecord()
        {
            if (myRecord == null)
            {
                //unzip and overwrite FileRecord
                UnZipFile();
                //return myRecord
                return myRecord;
                 }
                 else return myRecord;
            }
            ...
            ...
        } 

现在,使用这些FileRecords和ZippedFileRecords的代码部分是用户可以获取certian日期范围内的所有FileRecords,并获取屏幕上显示的信息。由于ZippedFileRecords是Zipped Files的代表,因此必须先将其解压缩。这是用于查找要显示的文件的代码部分:

public GetFrames(DateTime desiredStartTime, DateTime  desiredEndTime)
{
    for(int fileIdx = mFiles.Values.Count-1; fileIdx >= 0; --fileIdx)
    {
        FileRecord rec = (FileRecord)mFiles.GetByIndex(fileIdx);
        if(rec.StartTime>= desiredStartTime && rec.EndTime<=desiredEndTime)
        {
            ...
        }
        else
        {
            ...
        }
    }
}

造成我问题的行是FileRecord rec = (FileRecord)mFiles.GetByIndex(fileIdx);有没有办法让我查看天气mFiles [fileIdx]是ZippedFileRecord还是FileRecord?因为如果我能做到这一点,我只能根据需要解压缩而不是解压缩,然后每次在屏幕上显示时可能会重新压缩数百个文件只有一个或两个实际适合用户的日期范围

6 个答案:

答案 0 :(得分:2)

你可以这样做:

var zippedFileRecord = mFiles.GetByIndex(fileIdx) as ZippedFileRecord;

if (zippedFileRecord != null)
    ... do something with it

这样做会更干净:

foreach (var zippedFileRecord in mFiles.OfType<ZippedFileRecord>())
    ... do something with zippedFileRecord 

虽然看起来你正在通过列表向后搜索做一些特别的事情,但如果是这样的话,那就不行了。

但按类型过滤通常是代码味道。您可能应该向GetFileRecord()添加虚拟class FileRecord方法,以便在该类中适当地实现它。然后在class ZippedFileRecord中覆盖它,为该类做适当的事情。

然后你只需在循环中调用GetFileRecord()方法,而无需担心底层类型。

从中可以看出,GetFileRecord()class FileRecord的实施只会是:

public virtual FileRecord GetFileRecord()
{
    return this;
}

class ZippedFileRecord中的实现与您已编写的实现相同,但在声明中添加了override

public override FileRecord GetFileRecord()
{
    ...

然后你可以像这样使用它:

for(int fileIdx = mFiles.Values.Count-1; fileIdx >= 0; --fileIdx)
{
    FileRecord rec = ((FileRecord)mFiles.GetByIndex(fileIdx)).GetFileRecord();
    ...

最后一点:为什么不使用通用SortedList<TKey, TValue>,以便您可以使用强类型来避免投射?

答案 1 :(得分:1)

你可以这样测试:

if(mFiles.GetByIndex(fileIdx) is ZippedFileRecord)
{
   ...
}
else if(mFiles.GetByIndex(fileIdx) is FileRecord)
{
   ...
}

请注意,您需要按此顺序检查,因为ZippedFileRecord也是FileRecord,但反之亦然。

答案 2 :(得分:1)

使用is运算符 -

if(rec is ZippedFileRecord)
{
  //Unzip logic here
}
else
{

}

OR

在文件记录类中创建方法GetFileRecord() virtual,在override

中创建ZippedFileRecord方法
public class FileRecord
{
    public virtual FileRecord GetFileRecord()
    {
       return this;
    } 
} 

public class ZippedFileRecord : FileRecord
{
    public override FileRecord GetFileRecord()
    {
       // Unzip and retunr FileRecord instance.
    } 
}

这样您就不必担心类型了。这应该适用 -

FileRecord rec = mFiles.GetByIndex(fileIdx).GetFileRecord();

答案 3 :(得分:0)

您可以像这样使用is运算符

if (!(rec is ZippedFileRecord)) 
{
   // do your stuff in case rec is not ZippedFileRecord
}

答案 4 :(得分:0)

您可以使用“is”来检查对象是否属于特定类型:

if (rec is ZippedFileRecord) {
    ...
}
else {
    ...
}

编辑:有关更多选项,请参阅this question

答案 5 :(得分:0)

就个人而言,我想知道为什么ZippedFileRecord :: GetFileRecord必须解压缩文件。由于您只需要元数据,因此我重构该方法,以便在不解压缩文件的情况下设置元数据。然后,如果您确实需要文件数据本身,然后解压缩文件。