【问题标题】:Convert object to IEnumerable of anonymous type将对象转换为匿名类型的 IEnumerable
【发布时间】:2017-05-05 18:33:31
【问题描述】:

如何遍历作为(first, second, third) => new { One = first, Two = second, Three = third }下方的对象传入的anonymous type

如果我询问消息的类型并打印它,它会说:<>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                
);

【问题讨论】:

  • 你能设置断点并询问模式以查看它是什么类型以及它是否实现了 IEnumerable?
  • 在 C#dynamic 来做到这一点,但这实际上不是匿名类型的用途,dynamic 并不是要将 C# 转换为 JavaScript。如果你将它传递给一个方法,它应该有一个真实的类型。即使是元组也可以。
  • @kevin 查看原帖
  • This 编程指南说,“您不能将方法、属性、构造函数或索引器的形式参数声明为具有匿名类型。将匿名类型...作为参数传递给方法,您可以将参数声明为类型对象。但是,这样做违背了强类型的目的。如果您必须存储查询结果或将它们传递到方法边界之外,请考虑使用普通的命名结构或类而不是匿名类型。”
  • @ed 是的,一个元组可以工作,因为这很容易处理。

标签: c# linq system.reactive anonymous-types


【解决方案1】:

匿名类型不打算被传递,你应该只在绝对必要时使用对象。此外,您不能迭代匿名类型 - 您应该使用 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                
);

【讨论】:

    【解决方案2】:

    这对我有用:

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

    【讨论】:

    • 如果你有几个而不是一个怎么办?
    • @Ivan void Test(dynamic d) { foreach (dynamic item in d) { /* stuff */ } -- 测试,工作。
    • 啊哈!谢谢,这就是我所缺少的。
    • @Ivan 但是看在上帝的份上,写一个快速课程,或者至少使用一个元组。
    • 或者路杀
    【解决方案3】:

    匿名类型不应该被传递,原因与我们在 C# 中的强类型完全一样:编译器不会犯粗心的错误或忘记事情,我们经常这样做。如果您的匿名类实例离开了它们创建的范围,那么是时候让它们长大并成为一个真正的类了。

    通常我会说你应该编写一个具有适当属性的快速类(在这里猜测属性类型):

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

    但是Tuple<T1,T2,T3> 确实同样好,如果你有像OneTwoThree 这样的属性名称:

    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 有效,但dynamic 就像虎钳握把:“自 1921 年以来,每项工作始终都是错误的工具”。 dynamic 在类型系统中具有合法但很小的作用。它不存在,因此我们可以将整个语言转换为 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}");
        }
    }
    

    好的,Vise-Grip 也不是总是错误的工具。但很少有没有更好的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多