views:

1209

answers:

7

Hi,

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

+1  A: 

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.

Jehof
+6  A: 

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));
Pavel Minaev
thanks guys - by the way - should I have been able to (if I was more up on C#) worked this out by just looking at the syntax for the method in the doco? (ie. Parameters, match, Type: System..::.Predicate<(Of <(T>)>), The Predicate<(Of <(T>)>) delegate that defines the conditions of the element to search for...
Greg
Parameter type restricts the type of delegate you may pass to the method, and thus the signature of the method or lambda you have to use to create that delegate. It does not, in and of itself, signify the use of lambdas anymore than any other delegate type does. Documentation for lambdas is here: http://msdn.microsoft.com/en-us/library/bb397687.aspx
Pavel Minaev
Delegate is similar to a function pointer. By looking at the signature (`delegate bool Predicate<T>(T obj)`) you can see that a predicate is a function (method) that takes a **single parameter of type T**, and returns a **bool**.
Groo
A: 
public void someMethod()
{
    Uri u= new Uri("www.test.com");
    CustomClass cc = this.files.find( p => { return p.Path == u; } );
}
Matthew Scharley
Why statement lambda?
Pavel Minaev
PEBCAK. Brain fart. Take your pick.
Matthew Scharley
A: 

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.

Daniel Mošmondor
A: 

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#.

Groo
A: 

people, and what is the solution for the .NET 2?

serhio
I've added a .NET 2 answer.
Stevo3000
thanks..............................................!
serhio
A: 

.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;});
}
Stevo3000