[英]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 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.