【问题标题】:List of Anonymous objects?匿名对象列表?
【发布时间】:2015-04-11 17:50:36
【问题描述】:

我有一个使用 List 类的类。当尝试设置 Add 函数来添加我的匿名类型时,我得到的只是错误。

我一直在寻找几个小时,据我所知,我看到的每个示例都在做同样的事情。所以我不明白这是怎么回事。

class fileHistory<Object> : List<Object>
{
    public new void Add(DateTime ts, int st)
    {
        base.Add( new { timeStamp = ts; status = st;} );
    }
}

【问题讨论】:

  • 你得到什么错误?
  • 您是否尝试声明泛型类型?您将标识符 Object 用作​​泛型类型参数,这非常令人困惑。
  • 这应该是List&lt;dynamic&gt;,而不是List&lt;object&gt;。稍后您将无法检索 timeStampstatus 属性,因为您无法强制转换为匿名类型。或者干脆让它成为一个命名类型,没有理由让它匿名。
  • 如果非要给它起名字,那不是很匿名吧?

标签: c# list anonymous-types


【解决方案1】:

您不需要在类定义中进行泛型声明,并且还需要将分号更改为逗号:

public class fileHistory : List<Object>
{
    public new void Add(DateTime ts, int st)
    {
        base.Add( new { timeStamp = ts, status = st} );
    }
}

【讨论】:

    【解决方案2】:

    对,你可以覆盖(不是多态性!检查我使用了 overwrite 这个词而不是 overrideList&lt;T&gt;.Add(T) 方法,但我相信你可以解决你的问题使用组合而不是继承,您的代码将完美运行:

    class fileHistory
    {
        private readonly List<object> _log = new List<object>();
    
        public void Add(DateTime ts, int st)
        {
             _log.Add( new { timeStamp = ts; status = st;} );
        }
    }
    

    顺便说一句,我在这里看到了三个设计缺陷:

    1. 匿名类型不适用于您的用例。如果您要添加具有这两个属性的对象,并且在像您这样的具体用例中执行此操作,也许您正在使用匿名类型,因为您懒于设计具有 2 个属性的类? ;)

    2. 由于#1,为什么要使用通用列表创建objects 列表?它违背了泛型的全部目的!!

    3. 我发现隐藏了AddList&lt;T&gt; 的一个糟糕的设计决策。在这些情况下使用组合而不是继承。另外,当 C# 支持方法重载时,我不知道您为什么要使用带有new 关键字的标识符重用。在List&lt;T&gt; 中,Add 的输入参数没有过载...

    我的建议是:因为使用了 C# 提供的花哨的语法糖,所以代码并不花哨。有时你不需要它,老实说,我相信是这样的。

    对于那些担心 LINQ 的人...

    任何类都可能实现也可能不实现IEnumerable&lt;T&gt;。整个fileHistory 类可以使用foreach 或LINQ 及其实现IEnumerable&lt;T&gt; 的扩展方法进行迭代:

    // Check that I dropped the lazy approach of using 
    // anonymous types!!
    class fileHistory : IEnumerable<FileLog>
    {
        private readonly List<FileLog> _log = new List<FileLog>();
    
        public IEnumerator<FileLog> GetEnumerator() 
        {
             return _log.GetEnumerator();
        }
    
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return _log.GetEnumerator();
        }
    
        public void Add(DateTime ts, int st)
        {
             _log.Add(new FileLog { timeStamp = ts; status = st;} );
        }
    }
    

    ...现在像这样的一些类即使使用组合而不是继承也可以被迭代:

    new fileHistory().Where(log => log.DateTime < DateTime.Now);
    

    【讨论】:

    • 你是对的,我希望这样做避免了只为两个属性创建一个额外的类。这似乎是很多额外的开销。我过去做过教程等,但这将是我第一个有实际目的的程序。
    • 我这边发生了一些事情,我以为我的最后一条评论丢失了,所以我重新输入了(大部分)它。然后当我碰到提交按钮时,我看到了我的双重帖子。由于我无法删除第二个,我想我至少要编辑它。
    • @doni49 是的,保持简单!
    【解决方案3】:
    class fileHistory<Object> : List<Object>
    {
        public new void Add(DateTime ts, int st)
        {
            // That's how it's supposed to be
            base.Add(new { timeStamp = ts, status = st });
        }
    }
    

    希望我有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      相关资源
      最近更新 更多