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.

10voto

Assaf S. Points 41

Voici une fonction que j'ai écrite qui clone un enregistrement de type T, en utilisant la réflexion. C'est une implémentation très simple, je n'ai pas géré les types complexes etc.

public static T Clone(T original)
{
    T newObject = (T)Activator.CreateInstance(original.GetType());

    foreach (var originalProp in original.GetType().GetProperties())
    {
        originalProp.SetValue(newObject, originalProp.GetValue(original));
    }

    return newObject;
}

J'espère que cela peut aider quelqu'un.

5voto

Justin Niessner Points 144953

Vous pourriez toujours restreindre la méthode pour n'accepter que les types qui implémentent l'interface ICloneable :

public T Clone(T what) where T : ICloneable
{
    if (what is RunProperties)
        return (T) what.Clone();
}

Mais comme votre méthode ne fonctionne vraiment qu'avec un seul type, vous pourriez la modifier légèrement et utiliser également l'opérateur as :

public T Clone(T what)
{
    var castWhat = what as RunProperties;
    if(castWhat != null)
        return castWhat.Clone();
}

1voto

rtalbot Points 1248

Vous pouvez utiliser une contrainte générique pour contraindre le type de T à un type qui implémente ICloneable.

1voto

jeroenh Points 12777

Vous êtes presque en train de donner la réponse vous-même:

Le type T n'a pas de méthode Clone

Aussi, quel est l'intérêt d'une méthode générique si vous ne faites quelque chose que pour un type?

La méthode Clone provient de l'interface ICloneable, donc vous pouvez implémenter votre méthode générique Clone, la rendant fonctionnelle pour tous les types qui implémentent ICloneable de cette manière:

public T Clone(T quoi) where T: ICloneable
{
   return (T) quoi.Clone();
}

0voto

Darin Dimitrov Points 528142

Vous pourriez utiliser une contrainte générique :

public T Clone(T what) where T: ICloneable
{
    if (what is RunProperties)
        return (T)what.Clone();
    ...
}

ou si le paramètre générique T est défini sur la classe contenant :

public class Foo where T: ICloneable
{
    public T Clone(T what)
    {
        if (what is RunProperties)
            return (T)what.Clone();
        ...
    }
}

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