В недавнем вопросе на Переполнении стека я спросил, как я мог бы проанализировать через имя файла к дополнительной meta информации о файле.
После того, как я работал через ту проблему, я решил, что мог бы хотеть создать новый тип объекта содержать метаданные и исходный файл. Я думал, что мог бы сделать что-то вроде этого:
class BackupFileInfo : FileInfo, IEquatable
{
//Properties and Methods here
}
Идея состояла бы в том, что я сохраню оригинал FileInfo
возразите при добавлении метаинформации в свойствах объекта, который реализует FileInfo
, такой как IsMainBackup
.
Однако FileInfo
изолируется, что означает, что другие классы не могут наследоваться ему.
Вместо этого я закончил со следующим:
class BackupFileInfo : IEquatable
{
public bool IsMainBackup { get; set; }
public int ImageNumber { get; set; }
public int IncrementNumber { get; set; }
public FileInfo FileInfo { get; set; }
//public BackupFileInfo() //constructor here
public bool Equals(BackupFileInfo other)
{
return (this.FileInfo.Name == other.FileInfo.Name
&& this.FileInfo.Length == other.FileInfo.Length);
}
}
Я ужасно не взволнован этим решением потому что вместо способности использовать BackupFileInfo.Length
, Я оказываюсь перед необходимостью использовать BackupFileInfo.FileInfo.Length
. Возможно, это уже - лучшая практика, но что-то не чувствует себя хорошо.
Существует ли лучший способ иметь дело с этой проблемой?
Это одна из классических композиций вместо примеров наследования, и вы пошли в правильном направлении.
Для решения проблемы с свойствами просто создайте свойство под названием Length
, которое делегирует инкапсулированный объект FileInfo
.
Вы можете просто разоблачить свойства в FileInfo, о которых вы заботитесь. Что-то вроде этого:
public long Length { get { return FileInfo.Length; } }
Очевидно, что это становится менее практичным, если вы хотите делегировать множество свойств FileInfo.
.Pass-thru?
class BackupFileInfo : IEquatable<BackupFileInfo>
{
public long Length {get {return FileInfo.Length;}}
//.... [snip]
}
Кроме того, реквизит под названием FileInfo
просит о неприятностях... в некоторых местах может потребоваться отключение от класса FileInfo
.
Вы можете добавить в свой класс оператор имплицитный.
Eg:
class BackupFileInfo .... {
/* your exiting code */
public static implicit operator FileInfo( BackupFileInfo self ){
return self.FileInfo;
}
}
Затем вы можете обращаться со своим объектом BackupFileInfo как с объектом FileInfo
BackupFileInfo bf = new BackupFileInfo();
...
int mylen = ((FileInfo)bf).Length;
При желании вы можете легко обернуть свойства информации о файле в свои собственные свойства.
public long Length
{
get
{
return this.FileInfo.Length;
}
}
Это на самом деле не решает Вашей большой проблемы, но, конечно, Вы можете просто сделать так, чтобы свойства, которые Вы хотите использовать, действовали как прокси-серверы к реальным свойствам, находящимся под ними. Например
public long Length
{
get {return FileInfo.Length;}
}
(Конечно же, с помощью элементарной нулевой проверки)
.