【问题标题】:How to add properties to anonymous object dynamically? [duplicate]如何动态向匿名对象添加属性? [复制]
【发布时间】:2011-11-30 15:42:14
【问题描述】:

可能重复:
Is it possible to declare an anonymous type in C# with a variable/dynamic set of fields?

我构建了一个查询构建器,它通过检查用户在我的 ASP.NET MVC3 应用程序中设置的一些 GET 值来构建查询。此查询构建器可以添加排序、限制和过滤(WHERE 子句),然后返回构造的查询。

然后,此查询将转到我的 Dapper 存储库,该存储库尝试使用以下命令执行查询:

using (IDbConnection connection = new MySqlConnection(ConnectionStringFactory.GetConnectionString(Database.Push)))
{
    connection.Open();

    return connection.Query<Notification>(query.QueryString,
                                          new 
                                          {
                                              someAnonymousStuffHere = SomeValue
                                          });
}

但是,查询的参数(它是一个准备好的语句)需要放在匿名类型中。问题是:我不知道如何动态构造这个匿名类型。我现在所做的是将所有参数推送到查询构建器中的 Dictionary 中,其中键是属性的名称,值是值。

我不能只在我的查询构建器中定义一个匿名类型,因为该构建器由几个步骤组成,其中一些没有被执行。所以有时我们有 5 个参数,有时我们有 3 个参数,等等。

我希望我能清楚地解释我的问题。

【问题讨论】:

  • 你打算如何处理这个在编译时你不知道成员的匿名类型?
  • 匿名类型进入 Query 方法,这可能会将参数映射到查询中的正确占位符。

标签: c# .net asp.net asp.net-mvc-3


【解决方案1】:

匿名类型只是一种方便,编译器可以“即时”为您创建一个类型,以节省您的打字时间。但是,它仍然是静态类型的。如果您需要一种比匿名类型具有更多功能的“更智能”类型,或者如果您需要传递该类型的实例,则需要像在匿名类型存在之前一样创建一个“真实”类型。

另一个选择是使用dynamic 功能。您可以使用例如ExpandoObject 创建动态类型。这是一个关于如何使用它的小例子:

dynamic expando = new ExpandoObject();
expando.Name = "Martin";
if (((IDictionary<String, Object>) expando).ContainsKey("Name"))
  Console.WriteLine(expando.Name);

expando 确实是一本美化的字典,使用字典代替(像你一样)可能会是一个更好的选择。

【讨论】:

    【解决方案2】:

    匿名类型在编译时仍然是静态类型的。我建议您查看 dynamic 语言功能,或坚持使用您的字典。

    这是一个从键/值字典加载动态对象的示例,然后像访问静态类型对象一样访问它。

    //linqpad
    void Main()
    {
        IDictionary<string,object> items = new Dictionary<string,object>();
        items.Add("test","123");
    
        dynamic props = DynamicProperties.LoadFromDictionary(items);
    
        string item = props.test;
    
        item.Dump();
    }
    
    
    public class DynamicProperties : DynamicObject
    {
        private DynamicProperties(){}
    
        private Dictionary<string, object> dictionary = new Dictionary<string, object>();
    
        public static DynamicProperties LoadFromDictionary(IDictionary<string,object> Dictionary)
        {
            dynamic dprop = new DynamicProperties();
            foreach(var item in Dictionary)
            {
                dprop.dictionary.Add(item.Key.ToLower(),item.Value);
            }
            return dprop;
        }
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            string name = binder.Name.ToLower();
            Console.WriteLine("Trying to get " + name);
            return this.dictionary.TryGetValue(name,out result);
        }
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            Console.WriteLine("TrySetMember: " + value.ToString());
            this.dictionary[binder.Name.ToLower()] = value;
            return true;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-13
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 2020-11-05
      相关资源
      最近更新 更多