简体   繁体   English

区分两类

[英]Differentiate between two classes

I have a class FileRecord and the class public class ZippedFileRecord : FileRecord , that get stored in SortedList mFiles which has all the FileRecords and ZippedFileRecords. 我有一个FileRecord类和一个public class ZippedFileRecord : FileRecord ,它们存储在具有所有FileRecords和ZippedFileRecords的SortedList mFiles中。 The issue I'm running into is that I need a way to differentiate between the two, each ZippedFileRecord has a FileRecord and a method called GetFileRecord() where it unzips the file associated with ZippedFileRecord and makes a FileRecord for it (as seen in the chunk below..) 我遇到的问题是,我需要一种区分两者的方法,每个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;
            }
            ...
            ...
        } 

now the portion of code that uses these FileRecords and ZippedFileRecords is something that a user can grab all the FileRecords in a certian date range, and get the info for those displayed on screen. 现在,使用这些FileRecords和ZippedFileRecords的代码部分使用户可以在特定日期范围内获取所有FileRecords,并获取屏幕上显示的信息。 Since ZippedFileRecords are representative of Zipped Files they must first be unzipped. 由于ZippedFileRecords代表压缩文件,因此必须首先将其解压缩。 here is the portion of code used to seek out the files to be displayed: 这是用于查找要显示的文件的代码部分:

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
        {
            ...
        }
    }
}

The Line that is causing me issues is FileRecord rec = (FileRecord)mFiles.GetByIndex(fileIdx); 导致我出现问题的行是FileRecord rec = (FileRecord)mFiles.GetByIndex(fileIdx); is there any way for me to check weather the mFiles[fileIdx] is a ZippedFileRecord or a FileRecord? 我有什么办法可以检查mFiles [fileIdx]是ZippedFileRecord还是FileRecord? because If I can do that I can unzip only as needed instead of unzipping and then rezipping potentially hundreds of Files every time they are to display on screen only to have one or two actually fit in the user's date range 因为如果可以的话,我只能根据需要解压缩,而不是解压缩,然后每次在屏幕上显示它们时,可能都会将数百个文件重新解压缩,以使一个或两个实际上适合用户的日期范围

You can do: 你可以做:

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

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

It would be cleaner to do: 这样做会更清洁:

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

Although it seems that that you are doing something special by going backwards through the list, so this wouldn't work if that's the case. 尽管您似乎在倒退列表中做了一些特别的事情,所以在这种情况下这是行不通的。

But filtering by type like that is often a code smell. 但是按这样的类型进行过滤通常会产生代码异味。 It may be that you should add a virtual GetFileRecord() method to class FileRecord implement it appropriately in that class. 可能您应该在GetFileRecord() class FileRecord添加虚拟GetFileRecord()方法,以在class FileRecord实现它。 Then override it in class ZippedFileRecord to do the appropriate thing for that class. 然后在class ZippedFileRecord重写它,以对该类执行适当的操作。

Then you just call the GetFileRecord() method in the loop without needing to worry about the underlying type. 然后,您只需在循环中调用GetFileRecord()方法,而不必担心基础类型。

From the look of it, your implementation of GetFileRecord() in class FileRecord would simply be: 从外观上看,您在GetFileRecord() class FileRecord实现GetFileRecord()class FileRecord很简单:

public virtual FileRecord GetFileRecord()
{
    return this;
}

And the implementation in class ZippedFileRecord would be the same as the one you already wrote, but with override added to the declaration: class ZippedFileRecord的实现与您已经编写的实现相同,但是在声明中添加了override

public override FileRecord GetFileRecord()
{
    ...

Then you could use it like this: 然后,您可以像这样使用它:

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

One last point: Why aren't you using the generic SortedList<TKey, TValue> so that you can use strong types to avoid casting? 最后一点:为什么不使用通用的SortedList<TKey, TValue>以便可以使用强类型来避免强制转换?

You can test it like this: 您可以像这样测试它:

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

Note, that you need to check it in this order, since a ZippedFileRecord is also a FileRecord, but not vice versa. 请注意,由于ZippedFileRecord也是FileRecord,因此您需要按此顺序进行检查,反之亦然。

Use the is operator - 使用is运算符-

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

}

OR 要么

Make the method GetFileRecord() virtual in File record class and override it in ZippedFileRecord 在文件记录类中将方法GetFileRecord() virtual ,并在ZippedFileRecord override

public class FileRecord
{
    public virtual FileRecord GetFileRecord()
    {
       return this;
    } 
} 

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

This way you don't have to worry for the type. 这样,您不必担心类型。 This should work then - 然后应该可以工作-

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

You could use is operator like this 你可以使用is运营商这样的

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

You can use "is" to check if an object is of a specific type: 您可以使用“ is”检查对象是否为特定类型:

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

edit: See this question for more options. 编辑:请参阅此问题以获取更多选项。

Personally, I'm wondering why ZippedFileRecord::GetFileRecord has to unzip the file. 就个人而言,我想知道为什么ZippedFileRecord :: GetFileRecord必须解压缩文件。 Since you only want the metadata, I'd refactor the method so that the metadata is set up without unzipping the file. 由于只需要元数据,因此我将重构该方法,以便在不解压缩文件的情况下设置元数据。 Then, if you actually need the file data itself, then unzip the file. 然后,如果您实际需要文件数据本身, 解压缩该文件。

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

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