2017-05-05 5 views
0

Comment puis-je itérer sur la anonymous type qui est transmis comme un objet ci-dessous (first, second, third) => new { One = first, Two = second, Three = third }objet Convertir IEnumerable de type anonyme

Si j'interroge le type de message et l'imprimer, il dit: <>f__AnonymousType0 3[MtApi.MtQuote,MtApi.MtQuote,MtApi.MtQuote]

//**How do I convert an object to the anonymous type?** 
static void ShowAnonymousTypeMessage(object message) 
{  

    foreach(var quote in message) 
    Console.WriteLine(
     quote.Instrument + ": " + quote.Bid.ToString() + quote.Ask.ToString()); 
} 

...

var pattern = observable1.And(observable2).And(observable3); 
var plan = pattern.Then((first, second, third) => new { One = first, Two = second, Three = third }); 
var zippedSequence = Observable.When(plan); 
zippedSequence.Subscribe(
    ShowAnonymousTypeMessage     
); 
+0

Pouvez-vous définir un point d'arrêt et interroger un modèle pour voir de quel type il est et s'il implémente IEnumerable? –

+0

En C# <= 6, vous pouvez le faire avec 'dynamic' mais ce n'est vraiment pas le cas pour les types anonymes, et' dynamic' n'est pas censé transformer C# en JavaScript. Si vous le passez à une méthode, il devrait avoir un type réel. Même un Tuple serait quelque chose. –

+0

@ kevin voir l'article original – Ivan

Répondre

0

Cela fonctionne pour moi:

static void Main() 
{ 
    var anon = new { Name = "Terry", Age = 34 }; 
    test(anon); 
} 

static void test(dynamic t) 
{ 
    Console.WriteLine(t.Age); 
    Console.WriteLine(t.Name); 
} 
+0

Et si vous en avez plusieurs pas un seul? – Ivan

+1

@Ivan 'void Test (dynamique d) {foreach (élément dynamique en d) {/ * stuff * /}' - testé, fonctionne. –

+0

Aha! Merci c'est ce qui me manque. – Ivan

1

types anonymes ne sont pas destinés à être passé autour et vous ne devez utiliser l'objet lorsqu'il est absolument nécessaire. De plus, vous ne pouvez pas itérer sur un type anonyme - vous devez utiliser un Array.

var pattern = observable1.And(observable2).And(observable3); 
var plan = pattern.Then((first, second, third) => new[] { first, second, third }); 
var zippedSequence = Observable.When(plan); 
zippedSequence.Subscribe(
    ShowAnonymousTypeMessage     
); 
0

types anonymes ne sont pas destinés à être passé autour, pour la même raison que nous avons typage fort en C# du tout: Le compilateur ne fait pas erreurs négligentes ou oublier des choses, et nous le faisons souvent. Si vos instances de classe anonymes quittent la portée où elles ont été créées, il est temps qu'elles grandissent et deviennent une véritable classe.

En général, je dirais que vous devriez écrire une classe quickie avec des propriétés appropriées (devinettes sur les types de propriété ici):

public class Thing { 
    public String One { get; set; } 
    public String Two { get; set; } 
    public String Three { get; set; } 
} 

Mais Tuple<T1,T2,T3> est tout aussi bon vraiment, si vous avez des noms de propriété comme One, Two, et de toute façon Three:

public static void Main() 
{ 
    var x = Enumerable.Range(0, 10).Select(n => new Tuple<int, string>(n, $"Item {n + 1}")); 

    Test(x); 
} 

private static void Test(IEnumerable<Tuple<int, string>> stuff) 
{ 
    foreach (var item in stuff) 
    { 
     Console.Write($"{item.Item1}: {item.Item2}"); 
    } 
} 

dynamic œuvres, mais dynamic est comme le Grip-Vise: "toujours l'outil incorrect pour chaque emploi, depuis 1921". dynamic a un rôle légitime mais petit dans le système de types. Ce n'est pas là, donc nous pouvons transformer toute la langue en JavaScript.

public static Main() 
{ 
    var x = Enumerable.Range(0, 10).Select(n => new { ID = n, Value = $"Item {n + 1}" }); 

    Test(x); 
} 

private static void Test(dynamic message) 
{ 
    foreach (dynamic item in message) 
    { 
     Console.Write($"{item.ID}: {item.Value}"); 
    } 
} 

OK, la Vise-Grip n'est pas toujours le mauvais outil soit. Mais il est rare qu'il n'y en ait pas de meilleur.