2015-04-22 1 views
1

La raison pour laquelle je pose cette question est parce que je veux créer une classe qui a toutes les fonctionnalités de la classe FileInfo (dérive de FileInfo), et me permet d'y ajouter mes propres propriétés.Existe-t-il une alternative à l'héritage des classes scellées?

Je pense qu'un exemple collaborera plus. Ce que je veux:

BindingList<FileInformation> files = new BindingList<FileInformation>(); 
public void GatherFileInfo(string path) 
{ 
    files.Add(new FileInformation(path)); 
    listboxFiles.DataContext = files; 
} 

class FileInformation : FileInfo 
{ 
    public bool selected = false; 
} 

Versus ce que je crains que je dois faire:

BindingList<FileInformation> files = new BindingList<FileInformation>(); 
public void GatherFileInfo(string path) 
{ 
    files.Add(new FileInformation(path)); 
    listboxFiles.DataContext = files; 
} 

class FileInformation : FileInfo 
{ 
    string path = "<whatever>" 
    FileInfo fileInfo = new FileInfo(path); 
    public bool selected = false; 

    public string Name 
    { 
     get { return fileInfo.Name } 
    } 
    //Manually inherit everything I need??? 
} 

L'avantage de cette situation serait que dans WPF vous pourriez simplement se lier à toutes les propriétés de la FileInformation de classe, y compris ceux de la classe FileInfo héritée.

Je n'ai jamais examiné cette question et je n'ai aucune idée de l'endroit où je devrais commencer à chercher, donc un exemple ou une piste sur la façon de le faire serait utile.

+2

Pourquoi peut » t vous exposer l'objet 'FileInfo' imbriqué dans votre classe' FileInformation' via une propriété publique, au lieu de déclarer un par un les wrappers pour ses propriétés? –

+0

Ce serait une possibilité, mais pour des raisons de lisibilité du code, je me demandais si cela était possible sans avoir à traverser les objets pour se lier à des propriétés comme: 'FileI.FullName'. Ce n'est pas toujours la meilleure pratique non plus. – DerpyNerd

+1

Vous ne devez pas hériter des classes pour des raisons de lisibilité du code. Si quelque chose est nuisible dans le même, vous essayez de l'utiliser. En outre, "Selected" est quelque chose que vous effectuez sur une interface utilisateur, il ne devrait probablement pas exister dans le modèle. – Kcvin

Répondre

2

Il n'y a vraiment aucun moyen d'hériter d'une classe scellée dans .Net. Vous pouvez écrire des méthodes d'extension, mais cela ne vous permet pas d'ajouter de nouvelles propriétés ou champs. La seule autre chose que vous pouvez faire est de simuler l'héritage, mais en créant votre propre classe qui inclut un champ du type de classe dont vous voulez hériter, puis d'exposer manuellement chaque propriété et méthode de la classe "base" en écrivant un wrapper méthode pour chacun. Ce n'est pas mal si la classe est petite, mais si c'est une grande classe, cela devient douloureux.

J'ai écrit des programmes de générateur de code pour utiliser la réflexion pour faire cela automatiquement pour moi. Ensuite, je prends la sortie de cela et l'étend. Mais ce n'est pas l'héritage vrai. Personnellement, je n'aime pas le concept de classes scellées car il empêche d'étendre ces classes. Mais je suppose qu'ils l'ont fait pour des raisons de performance.

+0

Voilà ce dont j'avais peur ... trop mauvais – DerpyNerd

+0

J'ai renoncé à chercher une solution paresseuse. Tu as tout à fait raison. – DerpyNerd

0

Comme FileInfo hérite de MarshalByRefObject, vous pouvez créer un proxy personnalisé qui imite un FileInfo et gère toutes les invocations dans vos propres implémentations. Cependant, vous ne seriez pas en mesure de lancer cela, et plus important encore, vous ne pouvez pas étendre une telle classe avec des propriétés personnalisées. De toute façon, si quelqu'un d'autre veut cela, SharpUtils ont des outils pour l'aider.

1

Pour hériter de la classe scellée essayez d'utiliser le design pattern Décorateur , l'idée de base est de créer une instance privée du OldClass, et mettre en œuvre manuellement tous ses méthodes comme:

public class NewClass 
{ 
    private OldClass oldClass = new OldClass(); 

    public override string ToString() 
    { 
     return oldClass.ToString(); 
    } 
    //void example 
    public void Method1() 
    { 
     oldClass.Method1(); 
    } 
    //primitive type example 
    public int Method2() 
    { 
     return oldClass.Method2(); 
    } 
    //chaining example, please note you must return "this" and (do not return the oldClass instance). 
    public NewClass Method3() 
    { 
     oldClass.Method3(); 
     return this; 
    } 
} 

public class Demo 
{ 
    static void Main(string[] args) 
    { 
     var newClass = new NewClass(); 
     newClass.Method3(); 
     WriteLine(newClass); 
    } 
}