Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add properties to anonymous object dynamically? [duplicate]

Possible Duplicate:
Is it possible to declare an anonymous type in C# with a variable/dynamic set of fields?

I've built a query builder that constructs a query by examining some GET values that the user has set in my ASP.NET MVC3 application. This query builder can add sorting, limiting and filtering (the WHERE clause) and then returns the constructed query.

This query then goes to my Dapper repository that tries to execute the query with:

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

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

However, the parameters for the query (it's a prepared statement) need to be put in an anonymous type. The problem is: I don't know how to construct this anonymous type dynamically. What I do now is pushing all the parameters into a Dictionary<string, string> in the query builder, where the key is the name of the property and the value is, well, the value.

I can't just define an anonymous type in my query builder because the builder consists of several steps, of which some aren't executed. So sometimes we have 5 parameters, sometimes we have 3 parameters, etc.

I hope I explained my problem clear enough.

like image 491
Leon Cullens Avatar asked Oct 04 '11 12:10

Leon Cullens


People also ask

What is dynamic property in c#?

In C# 4.0, a new type is introduced that is known as a dynamic type. It is used to avoid the compile-time type checking. The compiler does not check the type of the dynamic type variable at compile time, instead of this, the compiler gets the type at the run time.

How do you declare an anonymous object?

Typically, when you use an anonymous type to initialize a variable, you declare the variable as an implicitly typed local variable by using var. The type name cannot be specified in the variable declaration because only the compiler has access to the underlying name of the anonymous type.


2 Answers

Anonymous types are simply a convenience where the compiler can create a type for you "on the fly" to save you some typing. However, it is still statically typed. If you need a "smarter" type with more functionality than you get from an anonymous type or if you need to pass instances of the type around you need to create a "real" type as you would before anonymous types existed.

Another option is to use the dynamic feature. You can create a dynamic type by using for instance ExpandoObject. Here is a small example on how you can use it:

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

The expando is really a glorified dictionary and using a dictionary instead (like you do) might turn out to be a better option.

like image 63
Martin Liversage Avatar answered Sep 23 '22 04:09

Martin Liversage


Anonymous types are still statically typed at compile time. I'd suggest looking into the dynamic language features, or sticking with your dictionary.

Here is an example of loading up a dynamic object from a dictionary of key/values, then accessing it as if it was a statically typed object.

//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;
    }
}
like image 27
asawyer Avatar answered Sep 26 '22 04:09

asawyer