5 votes

Cloner un type générique

Je veux cloner un objet générique et préserver son type.

run.Append(style.Clone(BlackFont)); //run object accepte uniquement les objets RunProperties

public T Clone(T quoi) {
    if (quoi is RunProperties)
        return (T) quoi.Clone();
}

Cela ne fonctionne pas car le type T n'a pas de méthode Clone, comment puis-je surmonter cela sans effectuer de cast dans la première instruction.

run.Append((RunProperties) style.Clone(BlackFont)); //Je ne veux pas faire ça
//notez que cela ne fonctionnera pas car vous ne pouvez pas convertir T en RunProperties

Merci pour toute aide.

---MODIFICATION---

Il semble qu'il serait préférable pour moi de ne pas utiliser de génériques dans ce cas. Je vais diviser les données.

0voto

supercat Points 25534

Je suggérerais de définir une interface ISelf, avec une propriété en lecture seule appelée "Self", de type T (qui, dans toute implémentation, devrait renvoyer "this"). Ensuite, définissez ICloneable qui hérite de ISelf et implémente une méthode, Clone(), de type T.

Ensuite, si vous avez une méthode qui a besoin de quelque chose qui dérive du type Foo et qui est clonable, passez simplement cette méthode à un ICloneable. Pour utiliser l'objet passé en tant que "Foo", accédez à sa propriété "Self". Je suggérerais que les classes avec des méthodes de clonage publiques soient souvent scellées, mais étendent les types non scellés simplement en ajoutant un "wrapper" public "Clone". Cela permettra l'existence de types dérivés qui autorisent ou non le clonage.

Considérez la famille de classes Foo, CloneableFoo, DerivedFoo et CloneableDerivedFoo, et OtherDerivedFoo.

  • Foo ne fournit pas de méthode Clone publique; il pourrait être cloné sans difficulté et a une méthode MakeClone protégée.
  • CloneableFoo dérive de Foo et expose une méthode Clone publique qui enveloppe MakeClone et implémente ICloneable.
  • DerivedFoo est dérivé de Foo; comme Foo, il n'a pas de méthode Clone publique, mais offre une méthode MakeClone protégée.
  • CloneableDerivedFoo dérive de DerivedFoo et expose une méthode Clone publique qui enveloppe MakeClone et implémente ICloneable.
  • OtherDerivedFoo dérive de DerivedFoo, mais a des invariants de classe qui seraient rompus s'il était cloné ; il masque MakeClone avec une fonction vide taguée obsolète-erreur.

Étant donné ces relations, il serait utile pour une méthode d'accepter tout dérivé clonable de Foo, tandis qu'une autre méthode acceptera tout dérivé - clonable ou non - de DerivedFoo. La première méthode devrait utiliser un paramètre de type ICloneable, tandis que la seconde prend un paramètre de type DerivedFoo. Notez que si DerivedFoo était dérivé de CloneableFoo plutôt que de Foo, il ne serait pas possible d'avoir quelque chose dérivant de DerivedFoo sans promettre une méthode Clone publique.

-1voto

Alen.Toma Points 490

Utilisez FastDeepcloner que j'ai développé https://www.nuget.org/packages/FastDeepCloner/

    /// 
    /// Cloner l'objet, voir FastDeepCloner pour plus d'informations
    /// 
    /// 
    /// 
    /// 
    /// 
    public static List Clone(this List items, FieldType fieldType = FieldType.PropertyInfo)
    {
        return DeepCloner.Clone(items, new FastDeepClonerSettings()
        {
            FieldType = fieldType,
            OnCreateInstance = new Extensions.CreateInstance(FormatterServices.GetUninitializedObject)
        });
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X