Question

Sous C # 3.0 et .NET 3.5, imaginez qu’il existe une interface:

public interface INameable
{
  string Name {get;}
}

et de nombreuses classes immuables implémentant l'interface.

J'aimerais avoir une seule méthode d'extension

public static T Rename<T>(this T obj) where T : INameable
{ 
  ...
}

qui renvoie une instance encapsulée de l'objet d'origine avec uniquement le nom modifié et toutes les autres lectures de propriétés et appels de méthodes acheminés vers l'objet d'origine.

Comment obtenir une classe de wrapper générique pour cela, sans l'implémenter pour tous les types d'implémentation INameable? Pensez-vous que c'est possible?

Était-ce utile?

La solution

Non, ce n'est pas possible, sauf si T est contraint d'être une interface ou une classe avec tous les membres virtuels, et cette contrainte ne peut pas être spécifiée au moment de la compilation (bien que vous pouvez écrire un chèque d’exécution si vous êtes satisfait de cette approche.

La raison pour laquelle vous ne pouvez pas le faire pour des types arbitraires est que si vous prenez un objet de type T , vous devez alors retourner un objet pouvant être attribué à T . Si je passe un objet qui ressemble à ce qui suit ...

public sealed class SomeClass : INameable
{
    public string Name { get; }
    public string Abc { get; }
}

... alors il est impossible de créer un autre type pouvant être assigné à SomeClass . N'utilisez pas Reflection.Emit ou toute autre méthode, car le type est scellé.

Cependant, si vous êtes satisfait des restrictions que j'ai mentionnées, vous pouvez utiliser un élément tel que le cadre Castle DynamicProxy pour créer un type permettant de remplacer l'objet passé par un proxy et d'intercepter les appels à transférer ou à ré-implémenter. approprié.

Autres conseils

Oui, c'est possible, mais cela implique de générer du code en mémoire.

Vous pouvez consulter Reflection.Emit et ici .

Notez que cela impliquera beaucoup de code.

Autrement dit, si je suppose que je vous ai bien compris.

Voici ce que je pense que vous demandez:

SomeNameableObject a1 = new SomeNameableObject("ThisIsTheFirstName");
SomeNameableObject a2 = a1.Rename("ThisIsTheSecondName");
// a1 works, still has the name ThisIsTheFirstName
// a2 works, but everything is routed to a1,
//    except for the name, which is ThisIsTheSecondName

Est-ce correct?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top