2011-10-04 52 views
5

可能重复:
Is it possible to declare an anonymous type in C# with a variable/dynamic set of fields?如何动态添加属性到匿名对象?

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

该查询,然后去我试图与执行查询小巧玲珑库:

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

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

然而,用于查询的参数(这是一个事先准备好的声明)需要被放入一个匿名类型。问题是:我不知道如何动态构建这个匿名类型。我现在所做的是将所有参数推送到查询生成器中的字典中,其中键是属性的名称,值是值。

我不能在我的查询生成器定义匿名类型,因为建筑商包括几个步骤,其中的一些不执行。所以有时候我们有5个参数,有时我们有3个参数,等等

我希望我解释了我的问题不够清楚。随时索取更多信息:)提前致谢!

+0

有什么打算这个匿名类型的成员,你不知道在编译时怎么办? – Gabe

+0

匿名类型进入查询方法,该方法可能会将参数映射到查询中的正确占位符。 –

+0

http://stackoverflow.com/questions/7437043/is-it-possible-to-declare-an-anonymous-type-in​​-c-with-a-variable-dynamic-set-of应该有你的答案 –

回答

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

匿名类型都只是为了方便编译器在哪里可以“飞”创造型,为您节省您的一些打字。但是,它仍然是静态类型的。如果你需要一个比你从一个匿名类型获得更多功能的“更聪明”类型,或者你需要传递类型的实例,你需要创建一个“真实”类型,就像在匿名类型存在之前一样。

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

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

的Expando的真的是一个荣耀的字典和使用字典而不是(像你这样做)可能会变成是一个更好的选择。