Edit
My original question was not very clear, so I'd like to try to rephrase it now. Please let me know if I still miss the mark.
Essentially, I'm trying to return a new string, in which all substrings enclosed by brackets have been replaced by a string from an object in a list. As an abstract example, I want to do something like the following:
public class MyType () : IEquatable <Property>
{
public string id;
public override String ToString()
{
return id;
}
public bool Equals ( MyType other )
{
if ( other is MyType == false )
{
return false;
}
return this.id == other.id;
}
}
List<MyType> listOfCustomTypes = new List<MyType> ();
return Regex.Replace ( originalString, "{(.*?)}", d => listOfCustomTypes.Where ( t => t.id == d.Groups[1].Value ).FirstOrDefault ());
The problem I've run into, or, error, specifically, is Cannot convert lambda expression to delegate type (System.Text.RegularExpressions.MatchEvaluator) because some of the return types in the block are not implicitly convertible to the delegate return type.
I am assuming that it isn't allowed to use return types in delegates, or something, because I can normally access it's properties, or cast to string.
I've probably still managed to jumble my question, so if it helps, my full project can be seen here, and the relevant file for this question is here (specific line is 161).
Original Question
I'm trying to learn how to use delegates and lambdas, and in typical fashion, bit off more than I can chew. In the following code snippet, I define a class, which holds a list of classes. In another function, I'm trying to use a string to find a list item, and get a value from that item.
[XmlRoot ( "Replacers" )]
public class Replacers
{
[XmlElement ( "Property" )]
public List<Property> properties = new List<Property> ();
[XmlIgnore]
public static Replacers replacers;
}
public class Property : IEquatable <Property>
{
[XmlAttribute ( "id" )]
public string id;
[XmlElement ( "Value" )]
public List<Value> propertyValue = new List<Value> ();
public override String ToString()
{
return id;
}
public bool Equals ( Property other )
{
return this.id == other.id && this.propertyValue == other.propertyValue;
}
}
public static class GetVariable
{
public static string FromUser ( string originalString )
{
try
{
//return Regex.Replace ( originalString, "{(.*?)}", m => Replacers.replacers.properties.FindIndex ( m.Groups[1].Value ) );
} catch ( Exception e )
{
return "ERROR: Unable to find '" + Regex.Match ( originalString, "{(.*?)}" ) + "'";
}
}
}
The commented out line above is that I'm trying to figure out. How do I replace anything that matches the pattern {(.*?)} with a value from the list item of the same name.
Thanks for taking the time to consider my question!
TL;DR:
How do I iterate over a list using lambda, where the iteration returns the actual list item? As an example, I want to do something like: Regex.Replace ( input, pattern, m => myList.Where(listItem.identifier == m). I don't feel like I've made my question very clear, so please ask, if you're confused. Thank you!
Consider this example:
var foos = new[] { "aaa", "aba", "aca" };
var bars = foos.Where(f => f.Contains("b")).Select(f => Regex.Replace(f, "b", "d"));
foreach (var bar in bars)
Console.WriteLine(bar);
// Output:
ada
Edit: I'll try to address your comment
A lambda is just a shorthand for a delegate (a typed-method).
You're probably accustomed to types like int, string, double, Animal, etc.
Well, just extend that notion to method signatures.
You can think of any method signature as being a type.
Here's a method that returns a bool, and takes an int as a parameter:
bool A(int i) { ... }
So the signature can be viewed as a type.
A lambda is a shorthand for this. Here's a lambda, that takes an int, and returns a bool, just like the method signature above:
(x) => x % 2 == 0
Linq extension methods (Where(), Select(), etc) all take some delegate type, or lambda expression.
myCollection.Where(x => x % 2 == 0).Where(x => x > 10).Select(x => x * 2);
The beauty is you can keep chaining these extension methods, each one becoming an additional filter if you will.
Select() is special because it's a projection operation (it transforms the items in the collection). You can see it takes this odd parameter here:
Func<string, string> // or something like that, depends on the types in your collection
A Func is kinda like a delegate, but in a more generic sense. It's easy to understand. The first type arguments are the input parameters (think parameters of a method), and the last is the output (think the return type of a method)
Func<in, in, in, out>
Consider this:
// Here's a method signature
bool MyMethod(int a, int b)
// Here's a lambda of the same delegate type
(a, b) => a == b
// Here's a Func being assigned that lambda
Func<int, int, bool> func = (a, b) => a == b;
Related
I have read about Func<>, which says it iss a delegate and you can use it like for example:
Func<class,bool>
means you send a class or anything and get a bool result, this is what I got!
but what does the following mean?
Func<Class, bool> predicate
I have no idea, can you make it clear for me?
The former will not compile since class is a registered keyword and can only be used for class definitions.
The latter is a Func<T, TResult> which is a function that takes a parameter of type T and returns an object of type TResult. So in your case, the function takes an object of type Class and returns a bool.
The naming of Class is unfortunate but it’s actually allowed to use that identifier for a type. The following would be an example that takes such an object of type Class and then checks a property of it, returning true or false depending on the success of the comparison.
Func<Class,bool> predicate = obj => obj.Prop == "Foo";
var x = new Class();
x.Prop = "Foo";
Console.WriteLine(predicate(x)); // true
// with the following class definition
public class Class
{
public string Prop { get; set; }
}
A Func<> object is callable, just like methods, so we can use parentheses to call it and pass the object here. This would be equivalent to a method like this:
public bool predicate(Class obj)
{
return obj.Prop == "Foo";
}
But the usual way to use Func<> is using lambda expressions to be able to create functions quickly inline. This is very commonly used in LINQ where you use lambda expressions, and as such Func<> objects, all the time:
var filtered = listOfOjects.Where(obj => obj.Prop == "Foo").ToList();
// ^^^^^^^^^^^^^^^^^^^^^^^^
// this is the predicate function from above
// so you could also pass the predicate Func from above:
var filtered = listOfObjects.Where(predicate).ToList()
Func<MyClass,bool> is a delegate type
In Func<MyClass, bool> predicate , predicate is a delegate variable.
You would normally see something like
Func<MyClass, bool> predicate = c => c.IsValid;
...
if (predicate(myClass1)) DoSomething();
That's just how you instantiate the Func. Compare to a string:
string str;
If you want to instantiate and assign it at the same time, you do something like this:
Func<string, bool> isLongerThanThree = input => input.Length > 3;
isLongerThanThree("string"); // Returns "true"
Are you referring to the word predicate?
That's just the name of a parameter. Notice the similarity:
MyMethod(int myAge)
MyMethod(List<bool> myBooleans)
MyMethod(Func<Class,bool> myPredicate)
Also notice the similarities between:
int myAge = 30;
myAge is a variable of type int who has been given the value of 30.
Func<Class,bool> myPredicate = (x => x.IsAlive);
myPredicate is a variable of type Func<Class,bool> who has been given the value of (x => x.IsAlive).
Func<> is a delegate which represents a method which return a result. C# provides signatures for up to 15 input arguments, which should be enough to represent all possible methods you will ever need :)
it is hardly event to imagine method which has 15 input arguments. Beside Func<> there are also some special version of the delegate like Predicate<T> which is nothing else that Func<in T, bool TResult> or Action<> which represent a function without return value, return value is void.
Delegates(C# Programming Guide)
You can assign any method, static or instance or even anonymous with the matching signature to the Func<>. For example:
Func<MyClass, bool> predicate = (myClass) => {return true;} //anonymoys method
public class MyClass
{
public bool MyPredicate(MyClass myClass)
{
return true;
}
public static bool MyStaticPredicate(MyClass myClass)
{
return true;
}
}
Func<MyClass, bool> predicate = new MyClass().MyPredicate;
Func<MyClass, bool> staticPredicate = MyClass.MyStaticPredicate;
Hello every Linq experts,
I would like to know how can I solve the following:
There is a string array:
string[] words={"a#p#e","#pp#e","a##le"};
How can I get the word 'apple' by Linq?
Thanks a lot!
words.SelectMany(ar=>ar.Select((c,i)=>new{Index=i, Letter = c}).Where(o=>char.IsLetter(o.Letter))).OrderBy(o=>o.Index).GroupBy(o=>o).Select(g=>g.Key);
Most likely this can be simplified, but well, it works (put together quickly in LinqPad).
This assumes you're only working with letters (can be modified to use char.IsLetterOrDigit), or use other filtering in Where.
Also, especially for #MarkPeters, a query syntax, properly named version:
from partialWord in words
from characterWithPosition in partialWord.Select((character, position) => new{character,position})
where char.IsLetter(characterWithPosition.character)
orderby characterWithPosition.position
group characterWithPosition by characterWithPosition into allCharactersWithPositions
let singleCharacterWithPosition = allCharactersWithPositions.Key
select singleCharacterWithPosition.character
This should work:
string[] words = { "a#p#e", "#pp#e", "a##le" };
var apple = words
.Aggregate(
(str1, str2) => { return String.Concat(str1.Zip(str2,
(c1, c2) => c1 == '#' ? c2 : c1).ToArray());
});
It works by checking whether there are any not-wanted characters in the first string and replacing them with the corresponding characters from the second string. The merged string is then passed to the next iteration, where the next two strings are merged. Finally the result is returned.
#mrbraitwistle's answer is the proper solution; performing IEnumerable<char>.Zip method within a IEnumerable<string>.Aggregate method
This following answer provides explicit type definitions to the parts of #Gerino's answer, which uses quite a bit of anonyomous types and delegates; Additioanlly, this answer utilizes Linq.Expressions and IQueryable<T>;
There is a catch though, it is in the GetHashCode of IndexLetterPair type below.
We'll create a concrete type instead of declaring the anonymous type new { Index = i, Letter = c }; however, the GroupBy will not function properly unless we override the GetHashCode method of object (of which our type inherits). We are also going to implement the IEquatable interface (where T is another IndexLetterPair), this interface will be utlized by the IQueryable<T>.GroupBy method.
Additionally, well override the object.Equal method as well - though it is likely unnecessary to do so since the GetHashCode is overriden.
public class IndexLetterPair IEquatable<IndexLetterPair>
{
public int Index { get; set; }
public char Letter { get; set; }
public override int GetHashCode()
{
return new { Index = this.Index, Letter = this.Letter }.GetHashCode();
}
// (new IndexLetterPair() as object).Equals(new IndexLetterPair());
public override bool Equals(object obj)
{
return (this.GetHashCode() == obj.GetHashCode());
}
// new IndexLetterPair().Equals(new IndexLetterPair());
public bool Equals(IndexLetterPair other)
{
return (this.GetHashCode() == other.GetHashCode());
}
}
For convience, were going to declare an extension class and method of IQueryable<string> that executes/declares the sequence of our defined expressions.
using Linq.Expressions;
public static class MyQueryableStringExtensions
{
readonly static Func<char, int, IndexLetterPair> SelectCharIndexPairingClause = (c, i) => new IndexLetterPair() { Index = i, Letter = c };
readonly static Func<IndexLetterPair, bool> WhereIsLetter = (dyn) => char.IsLetter(dyn.Letter);
readonly static Expression<Func<string, IEnumerable<IndexLetterPair>>> ManyClause = (arr) => arr.Select(SelectCharIndexPairingClause).Where(WhereIsLetter);
readonly static Expression<Func<IndexLetterPair, int>> OrderByIndexClause = (pairing) => pairing.Index;
readonly static Expression<Func<IndexLetterPair, IndexLetterPair>> GroupByClause = (pairing) => pairing;
// if IEquatable<IndexLetterPair> is implemented ? uses IEquatable<IndexLetterPair>.Equals : (IndexLetterPair() as object).Equals
readonly static Expression<Func<IGrouping<IndexLetterPair, IndexLetterPair>, IndexLetterPair>> GroupSelectKeyClause = (pairing) => pairing.Key;
public static IQueryable<char> SelectManyGroupedLetterChars(this IQueryable<string> words)
{
return words.SelectMany(ManyClause)
.OrderBy(OrderByIndexClause)
.GroupBy(GroupByClause)
.Select(GroupSelectKeyClause)
.Select((pair) => pair.Letter);
}
}
string[] words = new string[] { "a#p#e", "#pp#e", "a##le" };
IQueryable<string> queryableWords = words.AsQueryable();
IQueryable<char> queryGroupedLetterChars = queryableWords.SelectManyGroupedLetterChars();
// string(char[]);
string word = new string(queryGroupedLetterChars.ToArray());
I have a requirement to modify a method so that it has an extra parameter that will take a lambda expression that will be used on an internal object to return the value of the given property. Forgive my probable incorrect use of terminology as this is my first foray into LINQ expressions!
I have tried searching for an answer, but as I mentioned, my terminology seems to be off and the examples I can find are far too complex or deal with expressions for collection functions such as .Where(), which I am familiar with.
What I have so far (cut down version):
class MyClass
{
private MyObject _myObject = new MyObject() { Name = "Test", Code = "T" };
private string MyMethod(int testParameter, ??? selector)
{
//return _myObject.Name;
//return _myObject.Code;
return ???;
}
}
I would like to call it something like this:
string result = _myClassInstance.MyMethod(1, (x => x.Name));
or:
string result = _myClassInstance.MyMethod(1, (x => x.Code));
Obviously the parts which I am missing is the selector parameter in MyMethod, how to apply it to the local variable and how to pass the required property into the method when I am invoking it.
Any help would be appreciated, also extra bonus points for a VB.NET solutions as well as unfortunately the final implementation needs to be in our lone VB project!
private string MyMethod(int testParameter, Func<MyObject, string> selector)
{
return selector(_myObject);
}
When using Func delegates, the last parameter is the return type and the first N-1 are the argument types. In this case, there is a single MyObject argument to selector and it returns a string.
You can invoke it like:
string name = _myClassInstance.MyMethod(1, x => x.Name);
string result = _myClassInstance.MyMethod(1, x => x.Code);
Since the return type of MyMethod matches the return type of your selector delegate, you could make it generic:
private T MyMethod<T>(int testParameter, Func<MyObject, T> selector)
{
MyObject obj = //
return selector(obj);
}
I don't know VB.Net but it looks like it would be:
Public Function MyMethod(testParameter as Integer, selector as Func(Of MyObject, String))
Return selector(_myObject)
End Function
and the generic version would be:
Public Function MyMethod(Of T)(testParameter as Integer, selector Func(Of MyObject, T))
Return selector(_myObject)
End Function
I will show you a different approach that is very flexible (see DotNetFiddle at the bottom): You can easily write your own LINQ functions to extend existing functions or write your own functions and benefit from the power of LINQ queries.
In this example, I am improving Linq's Distinct function in a way so you can specify a field, which is used for grouping.
Usage (Example):
var myQuery=(from x in Customers select x).MyDistinct(d => d.CustomerID);
In this example the query is being grouped by CustomerID and the first element of each group is returned.
Declaration of MyDistinct:
public static class Extensions
{
public static IEnumerable<T> MyDistinct<T, V>(this IEnumerable<T> query,
Func<T, V> f)
{
return query.GroupBy(f).Select(x=>x.First());
}
}
You can see that f, the 2nd parameter, is declared as Func<T, V>, so it can be used by the .GroupBy statement.
Coming back to the code in your question, if you have declared
class MyObject
{
public string Name;
public string Code;
}
private MyObject[] _myObject = {
new MyObject() { Name = "Test1", Code = "T"},
new MyObject() { Name = "Test2", Code = "Q"},
new MyObject() { Name = "Test2", Code = "T"},
new MyObject() { Name = "Test5", Code = "Q"}
};
you could use that with the newly defined function MyDistinct as follows:
var myQuery = (from x in _myObject select x).MyDistinct(d => d.Code);
which will return
Name Code
Test1 T
Test2 Q
or you can use .MyDistinct(d => d.Name) in the query, which returns:
Name Code
Test1 T
Test2 Q
Test5 Q
Notice that because MyDistinct is declared with the generics T and V, it recognizes and uses the right object types automatically and returns MyObject elements.
Advanced usage
Notice that MyDistinct always takes the first element of each group. What if you need a condition defining which element you need?
Here's how you can do it:
public static class Extensions
{
public static IEnumerable<T> MyDistinct<T, V>(this IEnumerable<T> query,
Func<T, V> f,
Func<IGrouping<V,T>,T> h=null)
{
if (h==null) h=(x => x.First());
return query.GroupBy(f).Select(h);
}
}
This modification either allows you to use it exactly as before, i.e. by specifying one parameter like .MyDistinct(d => d.Name), but it also allows you to specify a having condition such as x => x.FirstOrDefault(y => y.Name.Contains("1")||y.Name.Contains("2")) as a second parameter like so:
var myQuery2 = (from x in _myObject select x).MyDistinct(d => d.Name,
x=>x.FirstOrDefault(y=>y.Name.Contains("1")||y.Name.Contains("2"))
);
If you run this query, the result is:
Name Code
Test1 T
Test2 Q
null
because Test5 does not meet the condition (it does not contain 1 or 2), you're getting null in the 3rd row.
Note: If you want to expose just the condition, you can have it even simpler by implementing it as:
public static IEnumerable<T> MyDistinct2<T, V>(this IEnumerable<T> query,
Func<T, V> f,
Func<T,bool> h=null
)
{
if (h == null) h = (y => true);
return query.GroupBy(f).Select(x=>x.FirstOrDefault(h));
}
In this case, the query would just look like:
var myQuery3 = (from x in _myObject select x).MyDistinct2(d => d.Name,
y => y.Name.Contains("1") || y.Name.Contains("2")
);
so you don't need to write x=>x.FirstOrDefault(... condition ...).
Try it in DotNetFiddle
in C#
The parameter type you are looking for Func
private string MyMethod(int testParameter, Func<MyClass,string> selector){
return selector(_myObject);
}
in VB you still want Func the syntax is a little different.
Function MyMethod(ByVal testParameter As Integer, ByVal selector as Func(Of MyClass,string) as string
return selector(_myObject)
End Function
class MyClass
{
private MyObject _myObject = new MyObject() { Name = "Test", Code = "T" };
private string MyMethod(int testParameter, Func<MyObject, string> selector)
{
return selector(_myObject );
}
}
You can do that with a delegate of your selector:
delegate string SampleDelegate(MyObject obj);
private string MyMethod(int testParameter, SampleDelegate selector)
{
return selector(_myObject);
}
You are probably looking for the Delegate class ("Delegate" in VB, "delegate" in C#), or one of its subtypes.
This page has some examples you will probably find useful, especially near the bottom of the page.
Here is a VB example of what you would want to do:
Public Class MyClass
Private Property _myObject As MyObject = New MyObject With {.Name = "Test", .Code = "T"}
Private Function MyMethod(testParameter As Integer, selector As Func(Of MyObject, String)) As String
Return selector(_myObject).ToString
End Function
End Class
I'm running into a problem that I did not expect. An example will probably illustrate my question better than a paragraph:
UPDATED: Skip to last code-block for a more eloquent code example.
public class A
{
public string B { get; set; }
}
public class C : A { }
Here is some code from a method:
var a = typeof(C).GetMember("B")[0];
var b = typeof(A).GetMember("B")[0];
Expression<Func<C, string>> c = x => x.B;
var d = (c.Body as MemberExpression).Member;
Here are the results of some comparisons:
a == b //false
a == d //false
b == d //true
The first two are somewhat unexpected. I understand that even though B is not virtual, C could define a property with the same name with thew new operator, but in this case I did not.
The second is really the most surprising to me (and is the heart of my problem). Even though the parameter for the lambda is clearly defined as being of type C, it still returns it as if the property was accessed from the base class.
What I'm looking for is a way to get the MemberInfo from a lambda expression as if I had used reflection on the type of the parameter to get the MemberInfo. My project essentially stores MemberInfos in a dictionary of sorts and it needs to have functionality where you can access the elements by providing a lambda expression.
Restated code sample by Danny Chen
public class Base
{
public string Name { get; set; }
}
public class Derived : Base { }
//in Main
var parentMember = typeof(Base).GetMember("Name")[0];
var childMember = typeof(Derived).GetMember("Name")[0];
Expression<Func<Base, string>> parentExp = x => x.Name;
var parentExpMember = (parentExp.Body as MemberExpression).Member;
Expression<Func<Derived, string>> childExp = x => x.Name;
var childExpMember = (childExp.Body as MemberExpression).Member;
parentMember == childMember //false, good
parentMember == parentExpMember //true, good
childMember == childExpMember //false, why?
Take the type of the expression's (first) parameter, and say
Expression<Func<C, string>> c = x => x.B;
Type paramType = c.Parameters[0].Type; // first parameter of expression
var d = paramType.GetMember((c.Body as MemberExpression).Member.Name)[0];
What I'm looking for is a way to get the MemberInfo from a lambda expression as if I had used reflection on the type of the parameter to get the MemberInfo.
That's not a service that expression tree conversions on lambdas were designed to provide. If you're going to use a feature "off label" then you might not get the results that you want.
The purpose of expression trees is to proffer up the compiler's semantic analysis of the expression in a form amenable to analysis at runtime, rather than compile time for the purpose of constructing query objects that can be remoted over to databases.
The compiler's correct semantic analysis is that Name is declared as a property of Base and invoked on an instance of Derived, so that's exactly the information that you get out of the resulting expression tree.
Nice question. I use some other names to make it clearer.
public class Base
{
public string Name { get; set; }
}
public class Derived : Base { }
//in Main
var parentMember = typeof(Base).GetMember("Name")[0];
var childMember = typeof(Derived).GetMember("Name")[0];
Expression<Func<Base, string>> parentExp = x => x.Name;
var parentExpMember = (parentExp.Body as MemberExpression).Member;
Expression<Func<Derived, string>> childExp = x => x.Name;
var childExpMember = (childExp.Body as MemberExpression).Member;
parentMember == childMember //false, good
parentMember == parentExpMember //true, good
childMember == childExpMember //false, why?
When debugging you will find childExpMember.ReflectedType is Base, while childMember.ReflectedType is Derived. AFAIK DeclaringType shows where the member is declared, while ReflectedType shows where the member is reflected to (because of inheritance/overriding/etc). So I think it's a bug (no official confirmation).
I believe you need to pass the flag "FlattenHierarchy" into the bindingAttr parameter of GetMember.
From MSDN:
Specifies that public and protected static members up the hierarchy should be returned. Private static members in inherited classes are not returned. Static members include fields, methods, events, and properties. Nested types are not returned.
I can't work out how to do a "find" on a List I have based on use of a value that I'll pass in at run time. If you see my below code, I want to be able to find the CustomClass in the List for which it's Path parameter is equal to X, where X will be defined at run time.
Any ideas how to do such a find on a List? Or is this not possible without writing an iterator and doing the find manually? In which case perhaps there is a key'ed collection I should look at using instead?
private List<CustomClass> files;
public void someMethod()
{
Uri u= new Uri(www.test.com);
CustomClass cc = this.files.find( matchesUri(u) ); // WON'T LET ME DO THIS
}
private static bool matchesUri(List<CustomClass> cc, Uri _u)
{
return cc.Path == _u; }
public class CustomClass
{
private Uri path;
public Uri Path
{
get { return this.path; }
set { this.path = value; }
}
}
PS. I must admit I don't quite follow the predicate stuff in the doco at http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx
Use a lambda:
Uri u = new Uri("www.test.com");
CustomClass cc = this.files.Find(cc => cc.Path == u);
or if you still want a named method:
static bool matchesUri(CustomClass cc, Uri _u)
{
return cc.Path == _u;
}
Uri u = new Uri("www.test.com");
CustomClass cc = this.files.Find(cc => matchesUri(cc, u));
You can write
CustomClass cc = this.files.Find( p=> p.Path == u );
The Find() method returns null if no element was found that matches the predicate.
For completeness sake only, here is what you would do if you didn't want to use a lambda:
// Predicate must be a method with a single parameter,
// so we must pass the other parameter in constructor
public class UriMatcher
{
private readonly Uri _u;
public UriMatcher(Uri u)
{
_u = u;
}
// Match is Predicate<CustomClass>
public bool Match(CustomClass cc)
{
return cc.Path == _u;
}
}
And then use it as:
public void someMethod()
{
Uri u = new Uri("www.test.com");
UriMatcher matcher = new UriMatcher(u);
CustomClass cc = this.files.Find(matcher.Match);
}
Note that you are passing a reference to a method, not the result of the method -- Match vs Match().
Check this thread also: Predicate Delegates in C#.
public void someMethod()
{
Uri u= new Uri("www.test.com");
CustomClass cc = this.files.find( p => { return p.Path == u; } );
}
Try using anonymous method for search and use any local variable you wish inside of it. If that is not satisfactory, call out your normally defined delegate method.
.NET 2.0 answer using an anonymous delegate (note that this only works for C#, VB.NET does not have anonymous delegates).
public void someMethod()
{
Uri u= new Uri("www.test.com");
CustomClass cc = this.files.find(delegate(CustomClass oTemp) { return oTemp.Path == u;});
}
In Pavel's post marked as answer, I think the line:
CustomClass cc = this.files.Find(cc => cc.Path == u);
should be instead like:
CustomClass cc = this.files.Find(cc2 => cc2.Path == u);
This is because the expresion to the left of => is a variable definition (the type is inferred from the expression) - The compiler would gives a redefinition error otherwise.
This expression can also be written with an explicit definition as:
CustomClass cc = this.files.Find((CustomClass cc2) => cc2.Path == u);
Here is a solution that I used. I needed to pass several arguments and didn't want to use anything that would prevent me from editing the method during runtime, so I came up with this.
Obviously if you wanted to you could change it to a generic method (right term?) using type arguments. This also gets around the problem of lambdas in a method. Not sure if that applies to anonymous methods as well or not, but it is already separate so no big deal.
I don't know whether the reflection would have a performance hit or not.
private Predicate<ItemData> FindItemData(string search, string fieldName)
{
var field = typeof(ItemData).GetField(fieldName);
return delegate(ItemData item) { return (string)field.GetValue(item) == search; };
}
//in another method...
itemlist.Find(FindItemData(e.Row[2].ToString(), "ItemName"));