how to use foreach in linq - c#

I have read in some blog some time ago (sorry for being vague) that i could use a linq like the following
var list = from c in xml
select new
{
foreach(XElement el in c.Elements())
{
}
}
Does anyone know is it possible or is it just my imagination??
Thanks.

You can't use a foreach loop directly in an anonymous type initialization expression, no.
If you could tell us what you're trying to achieve, we could probably help you find the best way of doing it.

You can use the ToList() function to convert the elements to a list of List then you can use the ForEach Method on it. FYI when using LinqToXml I find the Descendants() more useful as it will do a full dive into the object model.
xml.Elements().ToList().ForEach(ele => DoSomething(ele));

It's your imagination. You can use the results of a linq query in a foreach loop, but you can't use a foreach loop like that in the declaration for an anonymous type.

Ok, I have an xml with two parts, first declares the fields in the xml and second part has data associated with the declaration in the first part. So what I am trying to do is, read the first of the field definition and use that to create anonymous class of the data in the second section. Trying not to hard code in the program since we get data from different sources with different field definitions.

Related

Obtain case label constant in Roslyn

I'm trying to gather the switch section label constants from a SwitchStatement with Roslyn. But while I can see in the Syntax Visualizer that the CaseSwitchLabelSyntax has a Value property with the corresponding constant and the declared symbol (SourceLabelSymbol) has a SwitchCaseLabelConstant property, I cannot seem to get that information from what I have in my code.
// SwitchStatementSyntax node;
// SemanticModel model;
foreach (var section in node.Sections) {
foreach (var label in section.Labels) {
var labelSymbol = model.GetDeclaredSymbol(label);
// Here I'm stuck
}
}
I could probably look whether the SwitchLabelSyntax is a CaseSwitchLabelSyntax or a DefaultSwitchLabelSyntax and cast accordingly. SourceLabelSymbol is actually internal, so I cannot access its properties. model.GetConstantValue(label) returns null.
But given that Roslyn always hands out interfaces I believe that there's a reason for that and wildly casting around feels a bit hacky to me. Is there a better option?
Note: I'm doing this to translate C# syntax into another language. Technically, first into a separate AST that is then converted to text again. Above code is from within a CSharpSyntaxWalker and I could probably just store my partially converted switch statement away, continue visiting its descendants and build it up piecewise.
But that means having more state, building statements in half a dozen distinct locations which leads to hard-to-read and -follow code. I'd rather avoid it here, if possible.
Closest from API is semanticModel.GetConstantValue method, but still you need to pass Value node to it like this:
section.Labels
.OfType<CaseSwitchLabelSyntax>()
.Select(l => semanticModel.GetConstantValue(l.Value))
.ToArray()
As you can see filtering out CaseSwitchLabelSyntax is required anyway.

C# How to Access a Specific Index of a List of classes

I have created a class called studentRecord, and it contains several properties such as Student Number, First Name, Last Name, Courses, and Credit Hours for keeping track of individual student records. I also have created a list called List<studentRecord> lstRecords = new List<studentRecord>(); that stores the various objects (students).
I understand adding a student object through using lstRecords.Add();, but am running in to trouble with editing the objects. The user is supposed to be able to enter a student number, and then be able to access and edit the properties of that specific instance of the object. I have come up with this code:
StudentRecord editRecord = lstRecords.Find(indexRecord =>
indexRecord.intStudentNumber == intChosenRecord);
(By the way, intChosenRecord is a variable I declared to keep track of which index they are looking for)
I understand that StudentRecord is declaring a new object of that type, and that editRecord is my new object's name. However, I run into problems with using the .Find() method. I realize that .Find() searches through the list to find something that matches up with in input. Therefore, I assume that the intChosenRecord is what the program is searching for.
However, I have no idea what indexRecord is! This is the only time that it is used within the code, and I can change it to any name I want without errors. Could someone explain what this code does, and what indexRecord is?
"indexRecord" is a variable which correspond to each student in the list.
"Find" stops and returns the current student once condition (or "predicate") at the right of "=>" is true.
Therefore you can name it as you want, as long as you use the same name at left and right of "=>"
A similar loop could be :
StudentRecord editRecord = null;
foreach(var indexRecord in lstRecords)
{
if(indexRecord.intStudentNumber == intChosenRecord))
{
editRecord = indexRecord;
break; // Exits the loop.
}
}
This code is not very clean, but I give it for the sake of clarity, since it does the same than yours with an "oldschool" loop, which is certainly more familiar for you.
See http://msdn.microsoft.com/fr-fr/library/bb397687.aspx for more details on this syntax.
And http://msdn.microsoft.com/fr-fr/library/bb397926.aspx for other methods than "Find".
indexRecord is the argument of the lambda expression. It can have any name you want. In your case, it represent a StudentRecord (an element of your list)
you can easily change your code by :
StudentRecord editRecord = lstRecords.Find(x => x.intStudentNumber == intChosenRecord);
You can learn more about lambda expression on many site, as http://www.dotnetperls.com/lambda
The variable editRecord refers to the match returned by Find(), so it's not creating a new object or new instance of anything; it's referring to an existing instance.
Think of indexRecord as an identifier used to iterate over all the items in a collection, like when you say:
var numbers = new List<int>();
foreach (var n in numbers)
{
// do something with n
}
You can replace n, or indexRecord, with any identifier you like.
When you are using "=>", you are using a lambda expression.
In your case, "indexRecord" is the variable name of the input parameter for your lambda expression "indexRecord.intStudentNumber == intChosenRecord". And indexRecord correspond to a student stored in your list.
I would suggest that you get familiar with the lambda expressions, because it is a powerful and common used feature of c#.
try this ..
List<int> idlist=lstRecords.select(t=>t.intStudentNumber).toList();
int index=idlist.indexof(intChosenRecord);
studentRecord record=lstRecords[index];
i always use this ...

C# how to determine, whether ArrayList contains object with certain attribute

I have an ArrayList of objects of my custom class. I would like to know, if ArrayList contains object with certain attribute. I do not care about the object, just if there is some. Yes, I could do this with foreach cycle, but I was wondering if there was more elegant way to do so.
Thanks for suggestions.
Well, to start with I'd suggest using List<T> instead of ArrayList. Then LINQ to Objects makes it really easy:
if (list.Any(x => x.HasFoo))
{
}
Or without LINQ (but still List<T>)
if (list.FindIndex(x => x.HasFoo) != -1)
{
}
If you really need to stick with a non-generic collection but have LINQ to Objects available too, you can use:
if (arrayList.Cast<YourType>().Any(x => x.HasFoo))
{
}
use Linq:
var query = from o in yourarray select o where o.atribute==ValueIWant;
`query.Count()` will return the number of objects that fit the condition.
check that msdn example: Linq example

Removing from list recursively in C#

I have the following recursive function that is used to search down a hierarchical tree and remove found objects from a list:
private List<Tag> RemoveInvalidTags(Device device, List<Tag> tags)
{
var childDevices = device.ChildDevices.Select(c => c.ChildDevice);
foreach (var child in childDevices)
{
tags.Remove(child.Tag);
RemoveInvalidTags(child, tags);
}
return tags;
}
What I am expecting this to do is remove all child device tags at this level from the tags list, call the function recursively for your children, then return that list up to the previous level.
Will this pass the tags list by reference and modify the original passed list? Or should I be doing something along the lines of
validTags = CollectValidTags(child, tags);
and adding up all the returned lists?
Will this pass the tags list by reference
No. The list object is passed "by value" (but see next). (ref or out is required to "pass by reference" in C#, but that is not being done here, nor does it need to be.)
and modify the original passed list?
Yes. This is because the list object is passed. And that list object is mutated. Passing a reference type (anything defined with class) never implicitly makes a copy/clone/duplicate. An object is what it is.
Now, back to "pass by value": the "value passed" is the value of the "reference" (internal, no need to concern with this): this calling strategy is better known as Call/Pass By Object Sharing in a langauge like C#. The same object is shared (just as if it were assigned to two different variables). (Value types -- a struct -- are different in that they (often) are copied/duplicated on the stack, but a List<T> is a class.)
Or should I be doing something along the lines of
It depends upon the desired semantics. Is the caller expecting the side-effects directly or indirectly? Can the mutation side-effect lead to unexpected scenarios? Make sure to document it either way. (I prefer the way that guarantees the initial object is not mutated.)
Hope that clears some things up.
Happy coding.
In your code you are modifying the items in your tags parameter and passing back the modified list as your result. You want to avoid modifying lists in this way - especially inside loops where it can cause you grief in many situations.
I have a LINQ-based alternative for you.
If I understand the intent of your code you want to do something like this:
Func<Device, IEnumerable<Device>> flatten = null;
flatten = d =>
{
return (new [] { d }).Concat(
from c in d.ChildDevices
from f in flatten(c)
select f);
};
var collectedValidTags = flatten(device).Select(d => d.Tag);
var result = tags.Except(collectedValidTags).ToList();
This approach doesn't pass your list of tags around so there is no chance of modifying your original list.
Does this help?
Short answer - your code will do what you want.
Long answer - you should read descriptions of what the ref keyword does. I would suggest you read as many descriptions as possible; there are many different ways to articulate it ("I like to think of it as... ") and some will work for you whilst others won't. If you read many descriptions (from people who understand it) then some kind of understanding should gel for you.
Here's a list to get you started:
Use of 'ref' keyword in C# (my answer)
C# ref keyword usage
Passing by ref?
Example of practical of "ref" use

Is there a way I can dynamically define a Predicate body from a string containing the code?

This is probably a stupid question, but here goes. I would like to be able to dynamically construct a predicate < T > from a string parsed from a database VARCHAR column, or any string, for that matter. For example, say the column in the database contained the following string:
return e.SomeStringProperty.Contains("foo");
These code/string values would be stored in the database knowing what the possible properties of the generic "e" is, and knowing that they had to return a boolean. Then, in a magical, wonderful, fantasy world, the code could execute without knowing what the predicate was, like:
string predicateCode = GetCodeFromDatabase();
var allItems = new List<SomeObject>{....};
var filteredItems = allItems.FindAll(delegate(SomeObject e) { predicateCode });
or Lambda-ized:
var filteredItems = allItems.FindAll(e => [predicateCode]);
I know it can probably never be this simple, but is there a way, maybe using Reflection.Emit, to create the delegate code dynamically from text and give it to the FindAll < T > (or any other anonymous/extension) method?
The C# and VB compilers are available from within the .NET Framework:
C# CodeDom Provider
Be aware though, that this way you end up with a separate assembly (which can only be unloaded if it's in a separate AppDomain). This approach is only feasible if you can compile all the predicates you are going to need at once. Otherwise there is too much overhead involved.
System.Reflection.Emit is a great API for dynamically emitting code for the CLR. It is, however, a bit cumbersome to use and you must learn CIL.
LINQ expression trees are an easy to use back-end (compilation to CIL) but you would have to write your own parser.
I suggest you have a look at one of the "dynamic languages" that run on the CLR (or DLR) such as IronPython. It's the most efficient way to implement this feature, if you ask me.
Check out the Dynamic Linq project it does all this and more!
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Great for simple stuff like user selected orderby's or where clauses
It is possible using emit, but you'd be building your own parser.
EDIT
I remember that in ScottGu's PDC keynote, he showed a feature using the CLI version of the .net framework that resembled Ruby's eval, but I can't find a URL that can corroborate this. I'm making this a commnity wiki so that anyone who has a good link can add it.
I stepped off the dynamic linq because it's limited in ways I want to search a collection, unless you prove me wrong.
My filter needs to be: in a list of orders, filter the list so that I have only the orders with in the collection of items in that order, an item with the name "coca cola".
So that will result to a method of: orders.Findall(o => o.Items.Exists(i => i.Name == "coca cola"))
In dynamic linq I didn't find any way to do that, so I started with CodeDomProvicer.
I created a new Type with a method which contains my dynamically built FindAll Method:
public static IList Filter(list, searchString)
{
// this will by dynamically built code
return orders.Findall(o => o.Items.Exists(i => i.Name == "coca cola"));
}
when I try to build this assembly:
CompilerResults results = provider.CompileAssemblyFromSource(parameters, sb.ToString());
I'm getting the error:
Invalid expression term ">"
Why isn't the compiler able to compile the predicate?

Categories