2013-07-01 6 views
0

Quand, en général, devrais-je utiliser des méthodes de reflet par rapport aux clones (peu profonds)?Réflexion ou clonage() C#

Si toutes mes classes ont des constructeurs blanc utilise la réflexion bien, ou est-il une meilleure pratique d'écrire

Clone() 
{ 
    return new MyClass(); 
} 

méthodes pour les classes qui en ont besoin?

Je peux voir que la méthode Clone est plus sécurisée, car elle peut être vérifiée au moment de la compilation, mais laquelle est plus rapide, et quand est-il préférable d'utiliser la réflexion?


Mise à jour. Je ne cherche pas de solution à un problème particulier, mais plutôt d'apprendre plus de théorie pour comprendre comment aborder des problèmes de cette nature. Cependant, pour le mettre dans un contexte, je fais un jeu, et je rencontre régulièrement ce problème. Par exemple, le jeu permet à l'utilisateur de "placer" certains objets. Lorsque vous cliquez plusieurs fois, le jeu doit créer plusieurs instances (d'une sous-classe inconnue). Je suis venu avec trois solutions:

a) Avoir le menu qui sélectionne l'objet que vous allez placer un type, et utiliser Reflection pour générer ce type à plusieurs reprises.

b) Faites en sorte que le menu contienne une instance de l'objet et utilisez Reflection pour créer de nouvelles instances. (Cela peut maintenant être remplacé par MemberwiseClone)

c) Avoir le menu contenant une instance de l'objet, et utiliser une méthode Clone pour créer de nouvelles instances après que le premier est placé.

Je suppose que C est le meilleur, mais je veux comprendre pourquoi.

La réponse du modèle que je suis à la recherche est le long des lignes de ce (s'il vous plaît développer, corriger et compléter le cas échéant): Méthode

A « Clone » va généralement faire plus que simplement appeler nouvelle() que vous indiquer dans votre question; il copiera certaines ou toutes les propriétés de l'instance qu'il clone. Un clone peu profond copie un nombre limité de propriétés, et un clone profond les copie toutes.

Si vous avez simplement besoin de créer une nouvelle instance d'une classe particulière, il est préférable d'utiliser Object.MemberwiseClone(). Vous devez utiliser des méthodes de clonage chaque fois que vous avez une référence à une instance, où vous savez que cette instance aura l'attribut ICloneable.

Activator.CreateInstance() doit être réservé à l'utilisation uniquement lorsque vous n'avez pas de référence à une instance, par exemple lorsque vous avez chargé des informations de classe à partir d'un fichier texte ou XXXXXXX. La manière d'aborder le problème de la création de nouvelles instances d'une classe inconnue consiste toujours à tenter de le faire via des méthodes de type compilateur, par exemple (par exemple Cloning), et d'utiliser Reflection uniquement lorsque cela est totalement impossible.

Comme un résumé des avantages et des inconvénients:

Clone/MemberwiseClone

Plus: Vérifié comme typesafe au moment de la compilation, ne plantera pas votre programme lors de l'exécution, plus rapide lors de l'exécution Inconvénients: ne peut pas toujours être utilisé

réflexion

Avantages/inconvénients: En face ci-dessus.

+0

Je pense que dans votre question vous savez déjà quand utiliser quoi. Si, à la compilation, vous savez créer un type, utilisez new(), si le type est obtenu dynamiquement en exécution, utilisez la réflexion. La réflexion est absolument plus lente. –

+2

Comment une méthode renvoie-t-elle un nouvel objet vide une méthode _clone_? –

+0

On ne sait vraiment pas ce que vous faites ici. Cloner un objet est beaucoup plus que d'appeler 'new' par rapport au type. Cloner un objet signifierait que vous clonez ** au moins ** un sous-ensemble de ses propriétés. En outre, quel est le pilote pour que vous envisagiez même d'utiliser la réflexion sur une méthode 'Clone' sur des objets clonables? Est-ce que vous ne voulez simplement pas construire la méthode? –

Répondre

1

Si vous vraiment voulez une copie superficielle alors vous pouvez très bien utiliser Object.MemberwiseClone et implémenter l'interface ICloneable.

public class Model : ICloneable 
{ 
    public object Clone() 
    { 
     return MemberwiseClone(); 
    } 
} 

Vous pouvez utiliser la réflexion pour effectuer une copie superficielle si vous le souhaitez vraiment. Je comprends qu'il est avantageux car il est automatisé et peut être étendu pour fournir une copie profonde. Cependant, la réflexion est plus lente que Object.MemberwiseClone() et n'est pas autorisée dans les environnements d'approbation partielle. C'est aussi plus de code à implémenter au départ. Read more here.

+0

Je ne savais pas à ce sujet. C'est utile, merci. – Haighstrom

+0

@Haighstrom cela répond-il à votre question? –

+0

Il fournit une meilleure méthode pour faire ce que j'ai déjà, mais je cherche une explication claire de quand la réflexion devrait et ne devrait pas être utilisée. C'est à dire. Quand le type ne serait-il pas connu au moment de la compilation? – Haighstrom

0

Pour créer une nouvelle instance d'une classe:

MyClass obj = new MyClass(); 

Pour cloner une instance:

MyClass clone = obj.Clone(); 

Si vous voulez faire de votre classe Cloneable vous devez implémenter l'interface ICloneable:

public class MyClass : ICloneable 
{ 
    public MyClass Clone() 
    { 
     MyClass clone = new MyClass(); 
     // Copy property values to clone-instance. 
     return clone; 
    } 
} 

Je n'arrive pas à comprendre pourquoi vous voulez impliquer Reflection dans la création de nouvelles instances.

+0

Je sais comment écrire une méthode de clonage. Ce que je ne sais pas, c'est pourquoi je devrais écrire MyThing.Clone() sur Activator.CreateInstance (MyThing.getType()). Ou quand la réflexion est nécessaire. – Haighstrom