简体   繁体   中英

Convert object to IEnumerable of anonymous type

How do I iterate over the anonymous type that is passed in as an object below (first, second, third) => new { One = first, Two = second, Three = third }

If I interrogate the type of message and print it, it says: <>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                
);

Anonymous types aren't intended to be passed around and you should only use object when absolutely necessary. Also you can't iterate over an anonymous type - you should use an 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                
);

This is working for me:

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);
}

Anonymous types aren't meant to be passed around, for the same reason we have strong typing in C# at all: The compiler doesn't make careless errors or forget things, and we often do. If your anonymous class instances are leaving the scope where they were created, it's time for them to grow up and be a real class.

Usually I'd say you should write a quickie class with appropriate properties (guessing at the property types here):

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

But a Tuple<T1,T2,T3> is just as good really, if you've got property names like One , Two , and Three anyway:

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 works, but dynamic is like the Vise-Grip: "Always the Wrong Tool for Every Job, Since 1921". dynamic has a legitimate but small role in the typesystem. It's not there so we can turn the whole language into 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, the Vise-Grip isn't always the wrong tool either. But it's rare there isn't a better one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM