Est-il possible qu'un type anonyme implémente une interface?
J'ai un morceau de code que j'aimerais travailler, mais je ne sais pas comment faire.
J'ai eu quelques réponses qui disent soit non, soit créer une classe qui implémente l'interface en construire de nouvelles instances. Ce n'est pas vraiment idéal, mais je me demande s'il existe un mécanisme pour créer une classe dynamique mince au-dessus d'une interface qui rendrait cela simple.
public interface DummyInterface
{
string A { get; }
string B { get; }
}
public class DummySource
{
public string A { get; set; }
public string C { get; set; }
public string D { get; set; }
}
public class Test
{
public void WillThisWork()
{
var source = new DummySource[0];
var values = from value in source
select new
{
A = value.A,
B = value.C + "_" + value.D
};
DoSomethingWithDummyInterface(values);
}
public void DoSomethingWithDummyInterface(IEnumerable<DummyInterface> values)
{
foreach (var value in values)
{
Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
}
}
}
J'ai trouvé un article sur l' encapsulation d'interface dynamique qui décrit une approche. Est-ce la meilleure façon de procéder?
c#
anonymous-types
Nick Randell
la source
la source
Réponses:
Non, les types anonymes ne peuvent pas implémenter une interface. Depuis le guide de programmation C # :
la source
Bien que cela puisse être une question vieille de deux ans, et bien que les réponses dans le fil soient toutes vraies, je ne résiste pas à l'envie de vous dire qu'il est en fait possible qu'une classe anonyme implémente une interface, même si cela prend un peu de triche créative pour y arriver.
En 2008, j'écrivais un fournisseur LINQ personnalisé pour mon employeur de l'époque, et à un moment donné, je devais pouvoir distinguer "mes" classes anonymes d'autres classes anonymes, ce qui signifiait les implémenter une interface que je pouvais utiliser pour taper check leur. Nous l'avons résolu en utilisant des aspects (nous avons utilisé PostSharp ), pour ajouter l'implémentation d'interface directement dans l'IL. Donc, en fait, laisser des classes anonymes implémenter des interfaces est faisable , il vous suffit de légèrement plier les règles pour y arriver.
la source
La diffusion de types anonymes sur des interfaces est quelque chose que je voulais depuis un certain temps, mais malheureusement, l'implémentation actuelle vous oblige à avoir une implémentation de cette interface.
La meilleure solution est d'avoir un type de proxy dynamique qui crée l'implémentation pour vous. En utilisant l'excellent projet LinFu, vous pouvez remplacer
avec
la source
DynamicObject
un type LinFu?System.Dynamic.DynamicObject
n'a qu'un constructeur protégé (au moins dans .NET 4.5).DynamicObject
qui est antérieure à la version DLRLes types anonymes peuvent implémenter des interfaces via un proxy dynamique.
J'ai écrit une méthode d'extension sur GitHub et un article de blog http://wblo.gs/feE pour prendre en charge ce scénario.
La méthode peut être utilisée comme ceci:
la source
Non; un type anonyme ne peut rien faire sauf avoir quelques propriétés. Vous devrez créer votre propre type. Je n'ai pas lu l'article lié en profondeur, mais il semble qu'il utilise Reflection.Emit pour créer de nouveaux types à la volée; mais si vous limitez la discussion aux choses au sein de C # lui-même, vous ne pouvez pas faire ce que vous voulez.
la source
La meilleure solution est simplement de ne pas utiliser de classes anonymes.
Notez que vous devez convertir le résultat de la requête en type d'interface. Il pourrait y avoir une meilleure façon de le faire, mais je ne l'ai pas trouvé.
la source
values.OfType<IDummyInterface>()
au lieu de lancer. Il ne renvoie que les objets de votre collection qui peuvent réellement être convertis en ce type. Tout dépend de ce que vous voulez.La réponse à la question spécifiquement posée est non. Mais avez-vous envisagé des cadres moqueurs? J'utilise MOQ mais il y en a des millions et ils vous permettent d'implémenter / stub (partiellement ou complètement) des interfaces en ligne. Par exemple.
la source
Une autre option consiste à créer une seule classe d'implémentation concrète qui prend les lambdas dans le constructeur.
Si tout ce que vous allez jamais à faire est converti
DummySource
àDummyInterface
, il serait alors plus simple d'avoir une seule classe qui prendDummySource
dans le constructeur et implémente l'interface.Mais, si vous devez convertir de nombreux types en
DummyInterface
, c'est beaucoup moins une plaque de chaudière.la source