The syntax of your attempt / target does not work in C #, unfortunately, but you can probably get something close to it.
I am not familiar with the dynamics of crm, so I make this assumption, the constructor for ColumnSet takes a variable number of string arguments and has a signature:
public ColumnSet(params string[] arguments)
You can create a lambda expression that returns the initializer of the object (to create an anonymous object) and use some reflection to invoke the constructor using the bindings of the initializer elements. If I understand what you're trying to accomplish, you want to use the existing object parameter names to pass these names to this constructor to create the object.
Here's how you can do it:
public static ColumnSet Create<T>(Expression<Func<T, object>> parameters) { var initializer = parameters.Body as NewExpression; if (initializer == null || initializer.Members == null) throw new ArgumentException("lambda must return an object initializer"); var memberNames = initializer.Members .Select(member => member.Name.ToLower()) .ToArray(); var ctor = typeof(ColumnSet).GetConstructor(new Type[] { typeof(string[]) }); return (ColumnSet)ctor.Invoke(new object[] { memberNames }); }
Then, to use it, name it as follows:
ColumnSetFactory.Create<Person>(p => new { p.PersonId, p.Name, p.Age }); // Personally I prefer to call it like this to let the compiler // infer the generic arguments ColumnSetFactory.Create((Person p) => new { p.PersonId, p.Name, p.Age });
To generate an equivalent call to the constructor:
new ColumnSet("personid", "name", "age");
You can even make column names and give them random values, the values ββthemselves will not be used, just the name of the member.
ColumnSetFactory.Create<Person>(p => new { p.PersonId, p.Name, p.Age, Foobar = 0, Boo = "rawr!!!", });
To generate an equivalent call to the constructor:
new ColumnSet("personid", "name", "age", "foobar", "boo");