Ответ 1
Это один из классических композиций вместо примеров наследования, и вы пошли в правильном направлении.
Чтобы решить вашу проблему с имуществом, просто создайте свойство Length
, которое делегирует инкапсулированный объект FileInfo
.
В недавнем вопросе о переполнении стека я спросил, как я могу проанализировать имя файла для дополнительной метаинформации о файле.
После того, как я справился с этой проблемой, я решил, что может захотеть создать новый тип объекта для хранения метаданных и исходного файла. Я думал, что могу сделать что-то вроде этого:
class BackupFileInfo : FileInfo, IEquatable<BackupFileInfo>
{
//Properties and Methods here
}
Идея заключалась бы в том, что я сохранил исходный объект FileInfo
, добавляя метаинформацию в свойства объекта, который реализует FileInfo
, например IsMainBackup
.
Однако FileInfo
запечатан, что означает, что другие классы не могут наследовать его.
Вместо этого у меня получилось следующее:
class BackupFileInfo : IEquatable<BackupFileInfo>
{
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
.
Вы можете добавить оператор неявный в ваш класс.
Например:
class BackupFileInfo .... {
/* your exiting code */
public static implicit 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;}
}
(Конечно, с нулевой проверкой).