How could i send a property of my class into function - c#

I have a function, where i could send all objects of all types of my project and it should iterate over properties and output their values:
public void ShowMeAll(IEnumerable<object> items);
IEnumerable<Car> _cars = repository.GetAllCars();
ShowMeAll(_cars);
IEnumerable<House> _houses = repository.GetAllHouses();
ShowMeAll(_houses);
Ok, for example, it's so. Now, i'd like to send into my ShowMeAll function a property, which over i'd like to OrderBy my items and then output. What is the most correct way to do this with a parameter of function?

Easiest way is to let LINQ do that for you, via the OrderBy() method. For example:
IEnumerable<Car> _cars = repository.GetAllCars();
ShowMeAll(_cars.OrderBy(car => car.Make));
IEnumerable<House> _houses = repository.GetAllHouses();
ShowMeAll(_houses.OrderBy(house => house.SquareFootage));
That way, you remove the requirement for ShowMeAll to be aware of the properties of the objects passed in. Since you're passing List<object>, I assume that's desired. :)

private static void ShowMeAll<TClass>(IEnumerable<TClass> items, string property)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(TClass));
PropertyDescriptor targetProperty = properties.Find(property, true);
if (targetProperty == null)
{
// Your own error handling
}
IEnumerable<TClass> sortedItems = items.OrderBy( a => targetProperty.GetValue(a));
// Your own code to display your sortedItems
}
You would call the method like this:
ShowMeAll<Car>(_cars, "Make");
I've left out the error handling because I do not know what your requirements are

private static void ShowMeAll<TClass>(IEnumerable<TClass> items, string property )
{
// 1. Discover property type ONCE using reflection
// 2. Create a dynamic method to access the property in a strongly typed fashion
// 3. Cache the dynamic method for later use
// here, my dynamic method is called dynamicPropertyGetter
IEnumerable<TClass> sortedItems = items.OrderBy( o => dynamicPropertyGetter( o ) );
}
Dynamic methods (easier than they look, and 50-100x faster than reflection in my tests): http://msdn.microsoft.com/en-us/library/exczf7b9.aspx
Expression builders can also get the job done: http://msdn.microsoft.com/en-us/library/system.web.compilation.expressionbuilder.aspx

kind of this?
public void Test()
{
var o = new[] {new {Name = "test", Age = 10}, new {Name = "test2", Age = 5}};
ShowMeAll(o, i => i.Age);
}
public void ShowMeAll<T>(IEnumerable<T> items, Func<T, object> keySelector)
{
items.OrderBy(keySelector)
.ToList()
.ForEach(t => Console.WriteLine(t));
}

Related

LINQ: use Expression inside Where with anonymous type

Goal: call a method that returns an Expression I can use to chain methods on an anonymous IQueryable.
Example:
var allProducts = from p in ctx.Products;
var customWhere = Product.GiveMeYourQuery();
var productsIWant = allProducts.Where(customWhere);
Console.Writeline("yeaaaaah!");
This is what I've come up with as to now, which, of course, doesn't work:
class MainClass
{
public static void Main(string[] args)
{
var list = new [] {
new { Name = "ciao", Age = 18 },
new { Name = "prova", Age = 28 },
new { Name = "mah", Age = 38 },
new { Name = "boh", Age = 48 }
};
var myAnon = list.Where(x => x.Name.Length > 2).AsQueryable();
var thisthat = new MainClass();
var subset = myAnon.Where(thisthat.Where);
}
public Expression<Func<T, bool>> Where<T>(T anon){
var expr = Expression.Lambda(Expression.Equal(Expression.Constant(anon), Expression.Constant(anon)));
return (Expression<Func<T, bool>>) expr;
}
}
Compiler wisdom:
../Program.cs(24,24): Error CS0407: A method or delegate 'System.Linq.Expressions.Expression LINQInjector.MainClass.Where(anonymous type)' return type does not match delegate `bool System.Func(anonymous type)' return type (CS0407) (LINQInjector)
I feel I'm pretty close, but I cannot really see the path.
Unfortunately I cannot just cast the a' object to a type I create because what the program should output is the SQL (yes, I'm basically building a querybuilder that feeds another tier the queries to execute) and because I'd have to create too many types anyway (each type for each possible chain of joins between tens of tables).
EDIT:
While I appreciate you trying to show me alternatives and workarounds, at this point I think there's none. This is my question: how to inject Expressions into an anonymous type. If this cannot be done just say so.
Since you want to access a property known at compile time of an object outside of the scope in which it's created, you don't want to use an anonymous object. An anonymous object would be appropriate if you're accessing it using lambdas created in the same scope in which the anon object is created, but you don't want to do that. You want to have another method statically access a property of that object. Just give it a name, it'll make everything super easy:
public class Foo
{
public string Name{get;set;}
//...
}
public static Expression<Func<Foo, bool>> NameEquals(string name)
{
return foo => foo.Name == name;
}

Generic function that takes properties as parameters

I want to write a generic function that takes an object and a series of properties of this object. Inside the function I would like to select a new anonymous object that is simply just those properties of the passed in object.
I want to do something like this:
public class SimpleClass
{
public DateTime ADate {get; set;}
public string StringHere {get; set;}
public int ANumber {get; set;}
}
var testObj = new SimpleClass();
// set values here on testObj properties
DoStuffHere(testObj, StringHere, ANumber);
I could pass in the properties as strings and then use reflection to get the properties from the passed in object, but I wanted to know if there was some way I could pass in the properties themselves so I could have intellisense and compile time checking to prevent bad property names. I would like my getNewClass function to take any type of object, and such, be generic.
Edit: I am not returning a new anonymous type. I think my function name was making it sound that way. I am going to be selecting a new anonymous type internally from a list of that specified testObj and generating a PDF from those properties.
Defining an anonymous type is actually very complicated, and trying to do it just with the names is somewhat challenging. Essentially what you want already exists, but in regular C# - so for a single object:
var obj = new { testObj.StringHere, testObj.ANumber };
Or for multiple objects:
var projection = from obj in sequence
select new { obj.StringHere, obj.ANumber };
That's about as succinct as you'll get. You could add a generic method that took a Func<,> of some kind, but it wouldn't be any cleaner than the above.
It isn't useful to have:
var obj = SomeMagicMethod(obj, "StringHere", "ANumber");
because SomeMagicMethod could only usefully return object - our obj variable would be largely unusable.
If you don't need to return the object from the method, then you could use either of:
SomeMagicMethod<T>(T value) {
...
}
...
SomeMagicMethod(new {testObj.StringHere, testObj.ANumber });
or:
SomeMagicMethod<TFrom, TTo>(TFrom value, Func<TFrom, TTo> selector)
{
TTo actualVal = selector(value);
...
}
...
SomeMagicMethod(testObj, x => new {x.StringHere, x.ANumber });
Personally, I think the first is easier - the func in the second is overkill.
You could also just use reflection...
SomeMagicMethod(object obj, params string[] names)
{
foreach(var name in names) {
object val = obj.GetType().GetProperty(name).GetValue(obj);
// ...
}
}
//...
SomeMagicMethod(testObj, "StringHere", "ANumber");
you can pass them as lambda:
GetNewClass (testObj, ()=>StringHere, ()=> ANumber);
and have a signature for GetNewClass like
void GetNewClass (object, Expression<Func<object>> expr0, Expression<Func<object>> expr1);
You can then get the property quite easily.
You can use Linq expressions for that.
(note: it's possible you need to modify a few things in the snippet below, this is of the top of my hat):
public void getNewClass(Object testObj, params MemberExpression Fields[])
{
foreach(MemberExpression field in Fields)
{
// Get the name
var name = field.Member.Name;
// get the value
var member= Expression.Convert(field, typeof(object));
var lambda= Expression.Lambda<Func<object>>(member);
var fnc= lambda.Compile();
var value = fnc();
}
}
This snippet show how to get the name of the property and the value. It can be called like this:
getClass(someObj, obj => obj.SomeProperty, obj.SomeOtherProperty);

Using LINQ expression to assign to an object's property

So I'm working with an old data model, and I kind of have to work within what I've been handed.
When I perform a database query, the model returns data as a
List<Dictionary<string, object>>
Where for each dictionary, the key is the column name and the value is the column value. As you can imagine, working with this is a nightmare of foreach loops and type casting
I'm hoping to define some POCO viewmodels and then making something that uses LINQ/reflection, and an "assignment binding map" to go from hideous return value to my nice clean POCO. So I could define "maps" with the column names and lambdas to the properties on my POCO, similar to this...
var Map; // type???
Map.Add("Id", p => p.Id);
Map.Add("Code", p => p.Code);
Map.Add("Description", p => p.Description);
Map.Add("Active", p => p.Active);
Then convert like this...
List<Dictionary<string, object>> Results = MyModel.Query(...);
List<ProductViewModel> POCOs = new List<ProductViewModel>();
foreach (var Result in Results) // Foreach row
{
ProductViewModel POCO = new ProductViewModel();
foreach (var i in Result) // Foreach column in this row
{
// This is where I need help.
// i.Key is the string name of my column.
// I can get the lambda for this property from my map using this column name.
// For example, need to assign to POCO.Id using the lambda expression p => p.Id
// Or, assign to POCO.Code using the lambda expression p => p.Code
}
POCOs.Add(POCO);
}
return POCOs;
Can this be done using some sort of reflection, and if so, how?
Here is an approach using expression trees. First, define the API of the map:
public class PropertyMap<T> where T : new()
{
public void Add(string sourceName, Expression<Func<T, object>> getProperty);
public T CreateObject(IDictionary<string, object> values);
}
You would use it like this:
var map = new PropertyMap<ProductViewModel>();
map.Add("Id", p => p.Id);
map.Add("Code", p => p.Code);
map.Add("Description", p => p.Description);
map.Add("Active", p => p.Active);
var productViewModel = map.CreateObject(values);
To implement it, first you would declare a dictionary to associate names from the data source to properties:
private readonly IDictionary<string, PropertyInfo> _properties = new Dictionary<string, PropertyInfo>();
Next, you would implement the Add method in terms of that dictionary (all error handling left as an exercise for the reader):
public void Add(string sourceName, Expression<Func<T, object>> getProperty)
{
_properties[sourceName] = (PropertyInfo) ((MemberExpression) getProperty.Body).Member;
}
Then, you would dynamically compile a method, using expression trees, which does the assignments (it sounds scarier than it is). The easiest way to visualize this process is to look at an example of what we're building. What we want is some code which does this:
new ProductViewModel
{
Id = ...,
Code = ...,
Description = ...,
Active = ...
}
But, we can't know that at compile-time because of the dynamic mappings. So, we'll build a function which is that exact code, but compiled at runtime. Expression trees are just runtime data that represents the same code you could write at compile-time.
First, we need to get a set of bindings (assignments) for the properties:
private IEnumerable<MemberBinding> GetPropertyBindings(IDictionary<string, object> values)
{
return
from sourceName in _properties.Keys
select Expression.Bind(_properties[sourceName], Expression.Constant(values[sourceName]));
}
What we're saying here is, for each property in the mapped properties, look up the value and make it a constant (for Id, this might be the value 7) and bind the corresponding property to it. This gives us the expression Id = 7. We repeat this for all of the properties, giving us all of the assignments.
Once we have those bindings, we can create the full member initialization, which includes the constructor call:
private MemberInitExpression GetMemberInit(IDictionary<string, object> values)
{
return Expression.MemberInit(Expression.New(typeof(T)), GetPropertyBindings(values));
}
Because we specified where T : new() in the class declaration, we are guaranteed to have a parameterless constructor to call here. We pass in the property bindings we created before, giving us a data structure that represents the initialization expression we wanted to build.
So what do we do know? We have this data structure, but how do we call the code? To do that, we have to wrap that expression in a function that we can call, because the only thing you can actually invoke is a method. This means we are really building code that looks like this:
() => new ProductViewModel
{
Id = ...,
Code = ...,
Description = ...,
Active = ...
}
That is a parameterless function which, when invoked, will return the initialized object. This is also called a lambda expression. We can get the data structure for this like so:
private Func<T> GetInitializationFunction(IDictionary<string, object> values)
{
var initializationLambda = Expression.Lambda<Func<T>>(GetMemberInit(values));
return initializationLambda.Compile();
}
We create a lambda expression whose body is the member initialization, which is exactly the code we wrote above. We specify the delegate type Func<T> because it takes no parameters and returns an object of the mapped type.
Then, we compile it. This call generates a method with the signature Func<T> that we can call, and which has as its body the code we created as a data structure. This is a neat way of doing reflection without using reflection directly.
Finally, we implement the CreateObject method we defined earlier by creating the function and invoking it, giving us an instance of T (ProductViewModel here):
public T CreateObject(IDictionary<string, object> values)
{
var initializationFunction = GetInitializationFunction(values);
return initializationFunction();
}
What you could do is to extract the property name from a linq expression of the kind p => p.Id using something like this
public static string GetPropertyName<T>(Expression<Func<T>> expression)
{
MemberExpression body = (MemberExpression)expression.Body;
return body.Member.Name;
}
..and then use plain old reflection to actually assign the value to the object instance. For instance create a method
private void Assign(object objInstance, Expression<Func<T>> propertyExpression, object value)
{
string propertyNameToAssign = GetPropertyName(propertyExpression);
//TODO use reflection to assign "value" to the property "propertyNameToAssign" of "objInstance"
}
(didn't compile the code; for the reflection part, there are numerous articles on the web. Hope this helps)
This seems like a perfect match for dynamic . You can create a dynamic class that has the properties based on the keys in the dictionary. Check the DynamicObject class.

How to specify a list selection method?

I've got a method that computes a list. At certain points in the algorithm a single element from the list needs to be chosen. It doesn't really matter which element is chosen, but I'd like to leave it up to the user to decide.
Right now, I've added an extension method IList<T>.Random() which simply takes a random element. .First() would have worked equally as well. Supposing I want to let the user pick which method is used, or perhaps an entirely different method, how would that look?
I was thinking about using an enum with limited options, and then I could wrap each of these calls in a switch and call the appropriate function. But maybe some sort of lambda function would be more appropriate?
This method needs to be used in two different places, once on a List<char> and once on a List<string>. I want to use the same method for both.
This isn't a GUI app. I'm trying to decide how to design the API.
Specifically, I want to have a field like
public Func<IList<T>, T> SelectElement = list => list.First();
Which would then be used in the method,
public string Reverse(string pattern, IList<object> args = null, IDictionary<string, object> kwargs = null)
But generic fields aren't possible. So I'm looking for an alternative solution. One would be to make the SelectElement method an argument to Reverse(), then I could make it generic... but I was hoping to keep it at a class-level for re-usability. Don't want to pass any more args to the function if I can help it.
Edit: full source code
how about this:
public class MyClass
{
public static class C<T>
{
public static Func<IList<T>, T> SelectElement;
}
public int Test(IList<int> list)
{
return C<int>.SelectElement(list);
}
}
static class Program
{
static void Main(string[] args)
{
MyClass.C<char>.SelectElement = xs => xs.First();
MyClass.C<int>.SelectElement = xs => xs.First();
var list = new List<int>(new int[] { 1, 2, 3 });
var c = new MyClass();
var v = c.Test(list);
Console.WriteLine(v);
}
}
Here's an extremely basic example I put together using a generic method that takes in a Func<IEnumerable<T>, T> for selecting an item from the list and then returns the result. I've done a few examples of how to call it:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Test
{
class Program
{
static void Main(string[] args)
{
//Simple list.
var list = new List<int> { 1, 2, 3, 4 };
// Try it with first
var result = DoItemSelect(list, Enumerable.First);
Console.WriteLine(result);
// Try it with last
result = DoItemSelect(list, Enumerable.Last);
Console.WriteLine(result);
// Try it with ElementAt for the second item (index 1) in the list.
result = DoItemSelect(list, enumerable => enumerable.ElementAt(1));
Console.WriteLine(result);
}
public static T DoItemSelect<T>(IEnumerable<T> enumerable, Func<IEnumerable<T>, T> selector)
{
// You can do whatever you method does here, selector is the user specified func for
// how to select from the enumerable. Here I just return the result of selector directly.
return selector(enumerable);
}
}
}
If you want to limit the choices a user has you could follow the route of an enum and make this method a private method and then have a way to convert the enum to the appropriate selector delegate to pass to the underlying private method.
public Func<IList<object>, object> SelectElement = list => list.First();
private T _S<T>(IEnumerable<T> list)
{
return (T)SelectElement(list.Cast<object>().ToList());
}
I can make the anonymous method work on objects, thereby avoiding generics, and then add a helper method which is what I'll actually use to call it. A little ugly, but seems to work.
This works for chars and strings. Haven't tested with other types. Built this before I saw Ralph's code, which is practically the same.
LINQPad code:
void Main()
{
var chars = new List<char>();
var strings = new List<string>();
chars.AddRange(new char[] {'1','2','4','7','8','3'});
strings.AddRange(new string[] {"01","02","09","12","28","52"});
chars.Dump();
strings.Dump();
Func<IList<object>, string> SelectFirst = ( list )
=> list.First().ToString();
Func<IList<object>, string> SelectLast = ( list )
=> list.Last().ToString();
Func<IList<object>, string> SelectRandom = ( list )
=> list.ElementAt( new Random().Next(0, list.Count())).ToString();
SelectBy(SelectFirst, strings.Cast<object>().ToList()).Dump();
SelectBy(SelectFirst, chars.Cast<object>().ToList()).Dump();
SelectBy(SelectLast, strings.Cast<object>().ToList()).Dump();
SelectBy(SelectLast, chars.Cast<object>().ToList()).Dump();
SelectBy(SelectRandom, strings.Cast<object>().ToList()).Dump();
SelectBy(SelectRandom, chars.Cast<object>().ToList()).Dump();
}
private string SelectBy(Func<IList<object>, string> func, IList<object> list)
{
return func(list);
}

How to create LINQ Expression Tree to select an anonymous type

I would like to generate the following select statement dynamically using expression trees:
var v = from c in Countries
where c.City == "London"
select new {c.Name, c.Population};
I have worked out how to generate
var v = from c in Countries
where c.City == "London"
select new {c.Name};
but I cannot seem to find a constructor/overload that will let me specify multiple properties in my select lambda.
This can be done, as mentioned, with the help of Reflection Emit and a helper class I've included below. The code below is a work in progress, so take it for what it's worth... 'it works on my box'. The SelectDynamic method class should be tossed in a static extension method class.
As expected, you won't get any Intellisense since the type isn't created until runtime. Works good on late-bound data controls.
public static IQueryable SelectDynamic(this IQueryable source, IEnumerable<string> fieldNames)
{
Dictionary<string, PropertyInfo> sourceProperties = fieldNames.ToDictionary(name => name, name => source.ElementType.GetProperty(name));
Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicType(sourceProperties.Values);
ParameterExpression sourceItem = Expression.Parameter(source.ElementType, "t");
IEnumerable<MemberBinding> bindings = dynamicType.GetFields().Select(p => Expression.Bind(p, Expression.Property(sourceItem, sourceProperties[p.Name]))).OfType<MemberBinding>();
Expression selector = Expression.Lambda(Expression.MemberInit(
Expression.New(dynamicType.GetConstructor(Type.EmptyTypes)), bindings), sourceItem);
return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Select", new Type[] { source.ElementType, dynamicType },
Expression.Constant(source), selector));
}
public static class LinqRuntimeTypeBuilder
{
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static AssemblyName assemblyName = new AssemblyName() { Name = "DynamicLinqTypes" };
private static ModuleBuilder moduleBuilder = null;
private static Dictionary<string, Type> builtTypes = new Dictionary<string, Type>();
static LinqRuntimeTypeBuilder()
{
moduleBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run).DefineDynamicModule(assemblyName.Name);
}
private static string GetTypeKey(Dictionary<string, Type> fields)
{
//TODO: optimize the type caching -- if fields are simply reordered, that doesn't mean that they're actually different types, so this needs to be smarter
string key = string.Empty;
foreach (var field in fields)
key += field.Key + ";" + field.Value.Name + ";";
return key;
}
public static Type GetDynamicType(Dictionary<string, Type> fields)
{
if (null == fields)
throw new ArgumentNullException("fields");
if (0 == fields.Count)
throw new ArgumentOutOfRangeException("fields", "fields must have at least 1 field definition");
try
{
Monitor.Enter(builtTypes);
string className = GetTypeKey(fields);
if (builtTypes.ContainsKey(className))
return builtTypes[className];
TypeBuilder typeBuilder = moduleBuilder.DefineType(className, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable);
foreach (var field in fields)
typeBuilder.DefineField(field.Key, field.Value, FieldAttributes.Public);
builtTypes[className] = typeBuilder.CreateType();
return builtTypes[className];
}
catch (Exception ex)
{
log.Error(ex);
}
finally
{
Monitor.Exit(builtTypes);
}
return null;
}
private static string GetTypeKey(IEnumerable<PropertyInfo> fields)
{
return GetTypeKey(fields.ToDictionary(f => f.Name, f => f.PropertyType));
}
public static Type GetDynamicType(IEnumerable<PropertyInfo> fields)
{
return GetDynamicType(fields.ToDictionary(f => f.Name, f => f.PropertyType));
}
}
The accepted answer is very useful, but I needed something a little closer to a real anonymous type.
A real anonymous type has read-only properties, a constructor for filling in all of the values, an implementation of Equals/GetHashCode for comparing the values of each property, and an implementation ToString that includes the name/value of each property. (See https://msdn.microsoft.com/en-us/library/bb397696.aspx for a full description of anonymous types.)
Based on that definition of anonymous classes, I put a class that generates dynamic anonymous types on github at https://github.com/dotlattice/LatticeUtils/blob/master/LatticeUtils/AnonymousTypeUtils.cs. The project also contains some unit tests to make sure the fake anonymous types behave like real ones.
Here's a very basic example of how to use it:
AnonymousTypeUtils.CreateObject(new Dictionary<string, object>
{
{ "a", 1 },
{ "b", 2 }
});
Also, another note: I found that when using a dynamic anonymous type with Entity Framework, the constructor must be called with the "members" parameter set. For example:
Expression.New(
constructor: anonymousType.GetConstructors().Single(),
arguments: propertyExpressions,
members: anonymousType.GetProperties().Cast<MemberInfo>().ToArray()
);
If you used one of the versions of Expression.New that does not include the "members" parameter, Entity Framework would not recognize it as the constructor of an anonymous type. So I assume that means a real anonymous type's constructor expression would include that "members" information.
Maybe a bit late but may help to someone.
You Can generate dynamic select by call DynamicSelectGenerator in select from an entity.
public static Func<T, T> DynamicSelectGenerator<T>()
{
// get Properties of the T
var fields = typeof(T).GetProperties().Select(propertyInfo => propertyInfo.Name).ToArray();
// input parameter "o"
var xParameter = Expression.Parameter(typeof(T), "o");
// new statement "new Data()"
var xNew = Expression.New(typeof(T));
// create initializers
var bindings = fields.Select(o => o.Trim())
.Select(o =>
{
// property "Field1"
var mi = typeof(T).GetProperty(o);
// original value "o.Field1"
var xOriginal = Expression.Property(xParameter, mi);
// set value "Field1 = o.Field1"
return Expression.Bind(mi, xOriginal);
}
);
// initialization "new Data { Field1 = o.Field1, Field2 = o.Field2 }"
var xInit = Expression.MemberInit(xNew, bindings);
// expression "o => new Data { Field1 = o.Field1, Field2 = o.Field2 }"
var lambda = Expression.Lambda<Func<T, T>>(xInit, xParameter);
// compile to Func<Data, Data>
return lambda.Compile();
}
And use by this code:
var result = dbContextInstancs.EntityClass.Select(DynamicSelectGenerator<EntityClass>());
I don't believe that you will be able to achieve this. Although when you do select new { c.Name, c.Population } it seems like you're not creating a class you actually are. If you have a look at the compiled output in Reflector or the raw IL you will be able to see this.
You'll have a class which would look something like this:
[CompilerGenerated]
private class <>c__Class {
public string Name { get; set; }
public int Population { get; set; }
}
(Ok, I cleaned it up a touch, since a property is really just a get_Name() and set_Name(name) method set anyway)
What you're trying to do is proper dynamic class creation, something which wont be available until .NET 4.0 comes out (and even then I'm not really sure if it'll be able to achieve what you want).
You're best solution would be to define the different anonymous classes and then have some kind of logical check to determine which one to create, and to create it you can use the object System.Linq.Expressions.NewExpression.
But, it may be (in theory at least) possible to do it, if you're getting really hard-core about the underlying LINQ provider. If you are writing your own LINQ provider you can detect if the currently-parsed expression is a Select, then you determine the CompilerGenerated class, reflect for its constructor and create.
Defiantly not a simple task, but it would be how LINQ to SQL, LINQ to XML, etc all do it.
You could use the IQueryable-Extensions here, which is an implemantation of the solution described by "Ethan J. Brown":
https://github.com/thiscode/DynamicSelectExtensions
The Extension builds dynamically an anonymous type.
Then you can do this:
var YourDynamicListOfFields = new List<string>(
"field1",
"field2",
[...]
)
var query = query.SelectPartially(YourDynamicListOfFields);
You could use a parameter class instead of working with an anonymous type. In your example you can create a parameter class like this:
public struct ParamClass {
public string Name { get; set; };
public int Population { get; set; };
}
…and put it into your select like this:
var v = from c in Countries
where c.City == "London"
select new ParamClass {c.Name, c.Population};
What you get out is something of the type IQueryable<ParamClass>.
This compiles, I dunno if it works however...
myEnumerable.Select((p) => { return new { Name = p.Name, Description = p.Description }; });
Assuming p is what your transforming, and the select statement is returning an anon type, using the function declaration of lambda's.
Edit: I also don't know how you would generate this dynamically. But at least it shows you how to use the select lambda to return an anon type with multiple values
Edit2:
You would also have to bare in mind, that the c# compiler actually generates static classes of the anon type. So the anon type does actually have a type after compile time. So if your generating these queries at run time (which I assume you are) you may have to construct a type using the various reflection methods (I believe you can use them to make types on the fly) load the created types into execution context and use them in your generated output.
I think most of the things are already answered - as Slace said, you need some class that would be returned from the Select method. Once you have the class, you can use the System.Linq.Expressions.NewExpression method to create the expression.
If you really want to do this, you can generate class at runtime too. It's a bit more work, because it cannot be done using LINQ Expression trees, but it's possible. You can use System.Reflection.Emit namespace to do that - I just did a quick search and here is an article that explains this:
Introduction to Creating Dynamic Types with Reflection.Emit
You could use the Dynamic Expression API which allows you to dynamically build your select statement like this:
Select("new(<property1>,<property2>,...)");
You need the Dynamics.cs file from the LINQ and language samples for Visual Studio for this to work, both are linked at the bottom of this page. You can also see a working example showing this in action on at the same URL.

Categories

Resources