.net 3.5 anonymous foreach - c#

I'm trying to loop through the results of a function that is returning an anonymous object of results.
public static object getLogoNav()
{
XDocument loaded = XDocument.Load(HttpContext.Current.Request.MapPath("~/App_Data/LOGO_NAV_LINKS.xml"));
var query = from x in loaded.Elements().Elements()
select new
{
Name = x.FirstAttribute.Value,
Value = x.Value
};
return query;
}
codebehind page:
var results = Common.getLogoNav();
foreach(var nav in results) {
string test = nav.Name;
}

You can't have an anonymous class as a return type in C# 3 (and 4 for that matter) and you can't cast an object to an anonymous type. Your three options are:
Doing the loop within the scope of the anonymous class (most of the time, this is the method)
Casting to object and using reflection (slow and not very easy to do unless you do some expression tree magic)
Converting to a named class and returning and instance of that.
(In C# 4) you can create some dynamic type magic to achieve a similar effect but that would be really the same as option 2 with some syntactic sugar.

Jon Skeet wrote an entry about returning anonymous type. I hope you don't use it.

Related

C# Linq using variable for Model

Trying to write a piece of code that is dynamic in that it can accept any number of possible model definitions.
Current hard code is:
var items = _context.Events.ToList();
foreach (var item in items)
{
(...)
}
What I would like to do is to make the _context.Events.ToList(); be more like _context.{variable that holds model name}.ToList();
Something like:
var modelName = "Table1"
var items = _context.modelName.ToList();
foreach (var item in items)
{
(...)
}
I thought about declaring items as a generic variable, that way it was available to the entire method even if set inside an if or switch, but no idea on what to declare it as.
Is something like this possible?
Try this :
var table = (ITable)context.GetType()
.GetProperty(modelName)
.GetValue(context, null);
I hope be helpful :)
Entity Framework has a generic Set<TEntity> accessor, but the type must be known at compile-time:
var foo = _context.Set<Foo>();
If you have the type as a string variable, though, your options are extremely limited. You can technically use reflection to get at the right DbSet, but you're going to lose the generic IQueryable<TEntity> interface, and you'll be stuck with the much more limited IQueryable interface, and by "much more limited", I mean you basically can't do anything but materialize the set.
If you want to type it via a string variable, but still have at least some querying ability, you'll need to employ a base class that's shared between all the entity types you'd want to use in this way. For example, if you have different "event" types, and you can make them all inherit from Event, then you could do something like:
MethodInfo method = typeof(Queryable).GetMethod("OfType");
MethodInfo generic = method.MakeGenericMethod(new Type[] { eventType });
var set = (IQueryable<Event>)generic.Invoke(null, new object[] { _context.Events });
If your eventType was "Film", for example, that would effectively give you the same queryset as something like _context.Set<Film>() (where Film would be a derived class of Event). You could then utilize your normal LINQ query functionality like Where, Select, etc. on set.

Handling lambda expression with generic property name

Working with EPiServer Find and trying to build a generic facet funcionality for it to simplify managing which facet should be enabled. I would like to construct two generic methods, one for adding active filters to perform the hits search and one to perform the available facet filters remaining.
The first method will perform the following (specific code for brand filter):
var brandFilter = client.BuildFilter<FashionProduct>();
foreach (var facet in SelectedGroup.Facets.Where(x => x.Selected))
{
brandFilter = brandFilter.Or(x => x.Brand.Match(facet.Key));
}
query = query.Filter(brandFilter);
I would like to be able to call it in a generic way so I could base the available facets on some simple list of strings or objects. Like this:
query = AddFilterFacet<FashionProduct>(query, "Brand", SelectedGroup.Facets)
So the method would take the type of object to filter on, the query to append the filters on, the name of the property to filter on and the list of values to add.
The second method is similar but relates more to perform the following:
facetQuery = facetQuery.TermsFacetFor(x => x.Brand)
...
var brandFacets = facetResult.TermsFacetFor(x => x.Brand).Terms;
Is it possible to build this kind of functionality? The biggest questionmark I have is how to translate the "Brand" input string to be the Brand Property in x => x.Brand
private void AddFilterFacet<T>(IClient client, ref ITypeSearch<T> query, string propertyName, List<FacetOption> facets)
{
var filter = client.BuildFilter<T>();
foreach (var facet in facets)
{
filter = filter.Or(x => x.????.Match(facet.Key));
}
query = query.Filter(filter);
}
The .Or method takes a
System.Linq.Expressions.Expression<Func<T, Find.Api.Querying.Filter>>
so perhaps something can be used to make a proper generic call to it
It's definitely possible to create generic lambda expressions, it's just not easy and requires a lot of reflection code.
I haven't done it in a while, but maybe if you look at the code i created for something similar a while ago (Generic lambda expressions) it'll help. I'm sure someone with fresher experience will help you out here soon enough.
Decimal precision attribute <-- take a look a this answer witch has code to genereate modelBuilder.Entity<CLASS>().Property(OBJECT=> OBJECT.PROPERTY).HasPrecision(12, 10) automatically from an attribute in a class

Reflection: Setting properties of lots of objects using Dynamic Methods

So I have thousands of objects, of generic type T, and I want to cast them to an array of objects I got.
So I have to get the properties list T, and for each property set the value to the corresponding object on the array
for (int i = 0; reader.Read(); i++)
{
T tmp = (T)Activator.CreateInstance(typeof(T));
foreach (var prop in properties)
{
prop.SetValue(tmp, reader.GetValue(reader.GetOrdinal(prop.Name)), null);
}
}
reader is a DataReader. The problem I have is that prop.SetValue is sadly slow (consumes like 50% of the total excecution time), I've been told to use Dynamic Methods or Expression Trees, I tried using expression trees but from what I understood I have to generate one tree for each value I want to set, which wouldn't be so good.
So Dynamic Methods is the other option. Ideally I'd need to create a method SetProp(object, propertyName, value) which I can reuse over and over again.
Look at FastMember; either use it "as is", or steal all the code (DynamicMethod, etc). It does all this, with reflection-cache etc built in. Example usage:
var accessor = TypeAccessor.Create(typeof(T));
for (int i = 0; reader.Read(); i++)
{
T tmp = (T)Activator.CreateInstance(typeof(T));
foreach (var prop in properties)
{
accessor[tmp, propName] = newValue; // fill in name/value here
}
}
alternatively - use something like dapper-dot-net, that does that and handles all the materialization (since this is obviously data-access code).
I tried using expression trees but from what I understood I have to generate one tree for each value I want to set, which wouldn't be so good.
Why not? You'd basically build a List<Tuple<string, Action<object>>> by creating (and then compiling) an expression tree for each property in T. Then you iterate over the list and fetch the item for each property, then call the corresponding action.
I have a PropertyCopy class in MiscUtil which does something very similar - you may want to look at that for inspiration.
Alternatively, as of .NET 4 you could build a single Block expression tree which does all the property setting.
You can create a single expression tree for each property.
Just take the value as a parameter:
var instance = Expression.Parameter(typeof(T));
var value = Expression.Parameter(typeof(object));
var setter = Expression.Lambda(
Expression.SetProperty(instance, Expression.Cast(value, prop.PropertyType)),
instance, value
);
You would create and compile these expression trees once per instance type (typically in a static generic class).
While you're at it, you can probably make it even faster by compiling another expression tree instead of Activator.CreateInstance().

implicit type var [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Use of var keyword in C#
Being relatively new to C# I was wondering the motivation MS had to introduce the var implicit typed variables. The documentation says:
An implicitly typed local variable is strongly typed just as if you
had declared the type yourself, but the compiler determines the type.
Some lines further:
In many cases the use of var is optional and is just a syntactic
convenience
This is all nice but in my mind, this will only cause confusion.
Say you are reviewing this for loop.
foreach (var item in custQuery){
// A bench of code...
}
Instead of reviewing the content and the semantics of the loop, I would loose precious time looking for the item's type!
I would prefer the following instead:
foreach (String item in custQuery){
// A bench of code...
}
The question is: I read that implicit typed variables help when dealing with LINQ, does really help to use it in other scenarios?
The var keyword was needed when LINQ was introduced, so that the language could create a strongly typed variable for an anonymous type.
Example:
var x = new { Y = 42 };
Now x is a strongly typed variable that has a specific type, but there is no name for that type. The compiler knows what x.Y means, so you don't have to use reflection to get to the data in the object, as you would if you did:
object x = new { Y = 42 };
Now x is of the type object, so you can't use x.Y.
When used with LINQ it can for example look like this:
var x = from item in source select new { X = item.X, Y = item.Y };
The x variable is now an IEnumerable<T> where T is a specific type which doesn't have a name.
Since the var keyword was introduced, it has also been used to make code more readable, and misused to save keystrokes.
An example where it makes the code more readable would be:
var list =
new System.Collections.Generic.List<System.Windows.Forms.Message.Msg>();
instead of:
System.Collections.Generic.List<System.Windows.Forms.Message.Msg> list =
new System.Collections.Generic.List<System.Windows.Forms.Message.Msg>();
This is a good use of the var keyword, as the type already exists in the statement. A case where the keyword can be misused is in a statement like:
var result = SomeMethod();
As the SomeMethod name doesn't give any indication of what type it returns, it's not obvious what the type of the variable will be. In this case you should write out the type rather than using the var keyword.
I think some of the motivation was to allow something like this -
List<int> list = new List<int>();
to be turned into this -
var list = new List<int>();
The second example is shorter and more readable, but still clearly expresses the intent of the code. There are instances when it will be less clear, but in lots of situations you get conciseness with no loss of clarity.
var is really needed for anonymous types, which are used in Linq a bit:
var results =
from item in context.Table
select new {Name=item.Name, id=item.id};
Since the collection is of an anonymous type, it can not be named. It has a real type, but not one with a name before compilation.

How can I convert Anonymous type to Ttype?

How can I use Cast() Extension method for above conversion?
e.g.
var aType = anonymousType;
IEnumreable<MyType> = aType.Cast();
Solved By
aType.Select(i => new MyType { } ).ToList();
The only type that you can cast an anonymous type to is Object. If you want any other type, you have to create those objects from the data in the anonymously typed objects.
Example:
List<MyType> items = aType.Select(t => new MyType(t.Some, t.Other)).ToList();
You should consider to create the MyType objects already when you get the data, instead of creating anonymously typed objects.
Is aType is an IEnumerable<anonymous type> returned by e.g. a linq query?
You might want to use Select (which applies a transformation function to an element) insted of Cast which just performs a cast.
IEnumerable<MyType> = aCollection.Select(e => SomeExpressionWithE);
Here's an article that may help you. Although I think Guffa is right, you should create an instance of your class whenever you need them. Anonymous types are not meant to be used that way.
Here's the link:
http://www.codeproject.com/KB/cs/castinganonymous.aspx
IEnumreable<MyType> n = (IEnumreable<MyType>)aType;
http://msdn.microsoft.com/en-us/library/ms173105.aspx

Categories