【问题标题】:Get values from anonymous object从匿名对象中获取值
【发布时间】:2012-07-25 12:54:04
【问题描述】:

我有一个 ListView(在 WPF 应用程序中),我以编程方式填充它:

l1.Items.Add(new
{
    AA = aa++,
    Description = descriptions[k],
    Shop = names[k + 2],
    Price = price
});

我想取第一行和列价格的值。我可以拿走对象

object b = l1.Items.GetItemAt(0);

但我不能接受这个价格。

【问题讨论】:

标签: c# wpf listview anonymous-types


【解决方案1】:

您可以为此使用dynamic 关键字。

dynamic b = l1.Items.GetItemAt(0); 
var price = b.Price;

【讨论】:

    【解决方案2】:

    一旦匿名对象超出范围,您只能使用反射(不推荐)、动态(这会使您失去编译时类型安全)或其他一些技巧来访问其属性。

    最干净的解决方案是使用非匿名对象,即定义一个类:

    public class MyData {
        public int AA { get; set; }
        public string Description { get; set; }
        ...
    }
    
    ...
    
    l1.Items.Add(new MyData { AA = aa++, Description = descriptions[k], ...});
    
    ...
    
    MyData b = (MyData) l1.Items.GetItemAt(0);
    int aaValueOfB = b.AA;
    

    【讨论】:

    • dynamic 仍然理解事物的底层类型。
    • @AdamHouldsworth:它bypasses static type checking
    • 我从来没有说过,但是dynamic,在运行时,对底层对象有很好的理解。 DLR 会停止诸如无效强制转换、强制成员可访问性等事情。当然这是在运行时,但具有良好的单元测试覆盖率和一些常识,dynamic 关键字可以非常安全地使用。对于这个特定的问题,我只是不推荐它。
    • @AdamHouldsworth:啊,谢谢,我明白你的意思了。我修改了我的答案以澄清这一点(“你失去了 compile-time 类型安全”)。
    【解决方案3】:

    您可以使用 c# 4 中的dynamic 功能,如下所示:

    dynamic item = l1.Items.GetItemAt(0);
    double price = item.Price;
    

    您也可以使用反射(在幕后动态使用):

    object item = l1.Items.GetItemAt(0);
    Type t = item.GetType();
    PropertyInfo pi = item.GetProperty("Price");
    object price = pi.GetValue(item, null);
    

    或者,如果它在应用程序中有意义,只需将其声明为常规类,并照此使用。

    【讨论】:

      【解决方案4】:

      一旦它进入object,你就不能把它扔出去。你有两个选择:

      • 使用 dynamic 关键字将值直接输入。

        dynamic d = l1.Items.GetItemAt(0);
        var price = d.Price;
        
      • 使用实际类而不是匿名类型。

      就个人而言,我会上课:

      public class ItemsModel
      {
          // Define the properties, etc.
      }
      

      因为您可能希望实现 INotifyPropertyChanged 以进行数据绑定。

      【讨论】:

        【解决方案5】:

        正如那些人已经说过的,您可以使用 C# 中的 dynamic 关键字。 另一种选择(如果您知道您的对象结构)是使用反射来获取相关属性并提取其值。

        List<object> collection = new List<object>
        {
            new { Age1 = 1, Name = "Mr. Someone" } 
        };            
        
        // you can use reflection
        object anonymous = collection.First();
        var parameterInfo = anonymous.GetType().GetProperty("Name");
        string name1 = (string)parameterInfo.GetValue(anonymous, null);
        
        // another way
        dynamic dynamicObject = collection.First();
        string name2 dynamicObject.Name;
        

        【讨论】:

          【解决方案6】:

          试试这个:

          private static T GetAnonType<T>(T type, object obj)
                  {
                      return (T)obj;
                  }
          
          Object obj= l1.Items.GetItemAt(0);
          
          var info = GetAnonType(new { AA = aa++, Description = descriptions[k], Shop = names[k + 2], Price = price},obj);
          

          对 AA、描述等参数使用默认值。

          然后你可以使用,info.AA, info.Price 等。

          【讨论】:

            【解决方案7】:

            我是匿名类型的新手,但您可能需要将对象转换为该类型:

            private static T CastTo<T>(this Object x, T targetType)
            {
                return (T)x;
            }
            ...
            var tmp = new { AA = 0, Description = "", Shop = "", Price = 0.0}
            tmp = l1.Items.GetItemAt(0).CastTo(tmp);
            string price= "Price = " + tmp.Price;
            

            确保将使用正确的类型初始化 tmp 属性。

            【讨论】:

              猜你喜欢
              • 2014-10-15
              • 2013-08-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-07-30
              相关资源
              最近更新 更多