2012-02-12 12 views
13

Questo non sembra possibile? Quindi qual è il miglior work-around? Expando/dinamico?esegue il cast di un tipo anonimo su un'interfaccia?

public interface ICoOrd { 
    int x { get; set; } 
    int y { get; set; } 
}  

...

ICoOrd a = new {x = 44, y = 55}; 

ref:

+0

Sono solo curioso: cosa stai cercando di fare che richiederebbe di fare questo? Se conosci l'interfaccia, sai chiaramente quale funzionalità ha l'interfaccia, quindi puoi implementare una classe per fornire quella funzionalità, nel qual caso non hai più bisogno di un tipo anonimo, dato che puoi semplicemente creare un'istanza della tua classe. – xxbbcc

+0

Perché il tuo cast dovrebbe essere anonimo (non ci si "interessa" del suo design) a un'interfaccia (il che significa che si "cura" del suo design)? – gdoron

+2

@gdoron: un'interfaccia è una cosa utile da avere, e ho trovato che un buon uso dei tipi anon (nessun LINQ in questo caso) ha semplificato il mio codice * e * aiutato a rendere più chiara l'intenzione. Questa è la motivazione. Principalmente a che fare con strutture intermedie. – sgtz

risposta

27

La migliore "soluzione" consiste nel creare e utilizzare un tipo normale, di "nome" che implementa l'interfaccia.

Tuttavia, se si desidera utilizzare un tipo anonimo, è consigliabile utilizzare un framework proxy di interfaccia dinamica come ImpromptuInterface.

 var myInterface = new { x = 44, y = 55 }.ActLike<ICoOrd>(); 
+3

+1 per ImpromptuInterface. Puoi anche guardare Clay (clay.codeplex.com) –

+0

Sembra che tu abbia battuto il maestro Jon Skeet ... – gdoron

+2

+1 non sapevo che esistesse. ty. – sgtz

7

No, tipi anonimi non implementano interfacce. dynamic non consente di eseguire il cast dell'interfaccia, ma consente di accedere alle due proprietà. Si noti che i tipi anonimi sono internal, quindi se si desidera utilizzarli attraverso gli assembly utilizzando dynamic, sarà necessario utilizzare InternalsVisibleTo.

+1

+1: ty. Ho fatto un po 'di lettura su InternalsVisibleTo (link MS ora in questione). Questo è utile. Sembra un po 'laborioso. Hai visto InternalsVisibleTo utilizzato nel campo? – sgtz

+2

@sgtz: manodopera intensiva? È un singolo attributo. Ci vuole un po 'più di lavoro se si usano assiemi fortemente tipizzati, ma per il resto è molto semplice. Lo uso molto per i test unitari. –

+6

@sgtz: InternalsVisibleTo viene normalmente utilizzato per il test dell'unità; a volte si desidera eseguire il test dell'unità di una classe interna ma si desidera che l'assieme di prova sia un assembly diverso. Quindi dai al gruppo di test l'accesso agli interni. È usato raramente negli scenari di codice di produzione. Ricorda, gli assembly sono * versionable *; questo è l'intero * punto * delle assemblee. Nella maggior parte dei casi non si vorrebbe * modificare in modo indipendente le versioni * di due assiemi * che vedono l'interno dell'altro *. Se si dispone di due assembly che devono vedersi internals l'un l'altro, prendere in considerazione la fusione in uno. –

1

So che questa è una vecchia questione e risposte, ma mi sono imbattuto in questo su questo cercando di fare esattamente la stessa cosa per alcuni test di unità. Mi sono poi reso conto che sto già facendo qualcosa del genere usando Moq (facepalm).

Mi piace l'altro suggerimento per ImpromptuInterface ma sto già usando Moq e sento che avere un seguito più ampio (che è opinione e non fatto) sarà più stabile e supportato più a lungo.

quindi per questo caso sarebbe qualcosa di simile

public interface ICoOrd 
{ 
    int X { get; set; } 
    int Y { get; set; } 
} 

public class Sample 
{ 

    public void Test() 
    { 
     var aCord = new Mock<ICoOrd>(); 
     aCord.SetupGet(c => c.X).Returns(44); 
     aCord.SetupGet(c => c.Y).Returns(55); 

     var a = aCord.Object; 
    } 
} 

EDIT: semplicemente aggiungendo un altro modo per deridere il cavo, ha iniziato facendo in questo modo e, come un po 'meglio.

public void AnotherTest() 
{ 
    var aCord = Mock.Of<ICoOrd>(c => c.X == 44 && c.Y == 55); 
    //do stuff with aCord 
} 
Problemi correlati