This is my function:
private IEnumerable<string> SeachItem(int[] ItemIds) { using (var reader = File.OpenText(Application.StartupPath + @"\temp\A_A.tmp")) { var myLine = from line in ReadLines(reader) where line.Length > 1 let id = int.Parse(line.Split('\t')[1]) where ItemIds.Contains(id) let m = Regex.Match(line, @"^\d+\t(\d+)\t.+?\t(item\\[^\t]+\.ddj)") where m.Success == true select new { Text = line, ItemId = id, Path = m.Groups[2].Value }; return myLine; } }
I get a compile error,because "myLine" is not a IEnumerable[string] and I don't know how to write IEnumerable[Anonymous]
"Cannot implicitly convert type 'System.Collections.Generic.IEnumerable[AnonymousType#1]' to 'System.Collections.Generic.IEnumerable[string]'"
All LINQ methods are extension methods to the IEnumerable<T> interface. That means that you can call any LINQ method on any object that implements IEnumerable<T> . You can even create your own classes that implement IEnumerable<T> , and those classes will instantly "inherit" all LINQ functionality!
Usually, an anonymous data type is used in the select clause of a LINQ expression to return a subset of properties from each object in the collection. In the following code example, we will see using an anonymous object in a LINQ query.
In some cases, you might want to project a query to a new type, but the query would be your only use for the new type. Rather than create the type, you can project to an anonymous type.
You cannot declare IEnumerable<AnonymousType>
because the type has no (known) name at build time. So if you want to use this type in a function declaration, make it a normal type. Or just modify your query to return a IENumerable<String>
and stick with that type.
Or return IEnumerable<KeyValuePair<Int32, String>>
using the following select statement.
select new KeyValuePair<Int32, String>(id, m.Groups[2].Value)
I am not necessarily recommending this... It is a kind of subversion of the type system but you could do this:
1) change your method signature to return IEnumerable
(the non generic one)
2) add a cast by example helper:
public static class Extensions{ public static IEnumerable<T> CastByExample<T>( this IEnumerable sequence, T example) where T: class { foreach (Object o in sequence) yield return o as T; } }
3) then call the method something like this:
var example = new { Text = "", ItemId = 0, Path = "" }; foreach (var x in SeachItem(ids).CastByExample(example)) { // now you can access the properties of x Console.WriteLine("{0},{1},{2}", x.Text, x.ItemId, x.Path); }
And you are done.
The key to this is the fact that if you create an anonymous type with the same order, types and property names in two places the types will be reused. Knowing this you can use generics to avoid reflection.
Hope this helps Alex
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With