[Test]public void Evaluate(){ Dictionary<string, string> items = Hash(Name => "alex", Age => "10", Height => "20"); Assert.AreEqual("alex", items["Name"]); Assert.AreEqual("10", items["Age"]); Assert.AreEqual("20", items["Height"]);}
I got my desired result pretty quickly...
public Dictionary<string, T> Hash<T>(params Expression<Func<string, T>>[] args)where T: class{ Dictionary<string, T> items = new Dictionary<string, T>(); foreach (Expression<Func<string, T>> expression in args) { ConstantExpression itemValueExpression = expression.Body as ConstantExpression; if (itemValueExpression == null) throw new InvalidCastException("The body of the expression must be of type ConstantExpression"); T item = itemValueExpression.Value as T; items.Add(expression.Parameters[0].Name, item); } return items;}
But, then I tried this...
[Test]public void EvaluateForObjects(){ Dictionary<string, object> items = Hash<object>(Name => "alex", TargetType => typeof(Uri), Id => 10); Assert.AreEqual(10, items["Id"]);}
Which fails, the last key/value pair (Id => 10) isn't represented as a ConstantExpression, so to support it (and other eventualities) I modified my code a smidge...
public Dictionary<string, T> Hash<T>(params Expression<Func<string, T>>[] args)where T: class{ Dictionary<string, T> items = new Dictionary<string, T>(); foreach (Expression<Func<string, T>> expression in args) { ConstantExpression constantExpression = expression.Body as ConstantExpression; T item = null; if (constantExpression != null) { item = constantExpression.Value as T; } else { item = Expression.Lambda<Func<T>>(expression.Body).Compile()(); } items.Add(expression.Parameters[0].Name, item); } return items;}
Now... let's compare performance to say, adding the values using the Add method... so... for a million consecutive executions (in milliseconds) a quick test yielded these results...
Which I suspect tells me nothing more then the fact that the "Hash" style initialization is a lot slower, but not slow enough to completely discourage me.
Edit: There seems to be a bit of interest in this lately, so don't forget to take a look at the other related posts if you found this interesting.