Predicates are awesome

  • Thread starter Thread starter sklett
  • Start date Start date
S

sklett

I've finally had the time to make use or predicates and convert a bunch of
ugly loops over to predicates. SO much cleaner.
Anyway, my question is if there are plans (or maybe already existing) to add
List<> function that would call a predicate on every item like a process.

For example:
public static Predicate<MyObject> ApplyTax(float taxRate)
{
return delegate(MyObject item)
{
item.Tax = taxRate;
};
}

List<MyObject> objects = new List<MyObject>();
// code to add a ton of objects to the list

ojects.ProcessAll( ApplyTax(7.75) );



Is there anything like that already existing? I haven't seen anything, but
maybe I'm just dense.
Thanks for reading,
Steve
 
C++ uses Generic Algorithms to work on the STL-containers. Its a little hard
to get into but works very well to reorganize your code. I don't know if C#
has it.
 
Hi,

You can use ForEach method and delegate void Action<T>(T obj);.
I like this one:

List<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);

list.ForEach(Console.WriteLine);

Console.ReadLine();
 
Agreed. In fact, I find Generics in general to be possibly the most powerful
addition to the language.

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Numbskull

Hard work is a medication for which
there is no placebo.
 
Cool thing about methods that take a predicate delegate is that you can do what ever you want.

For example, the FindAll method will run your delegate over every item, so you can update each item and you may not even care about the return as you know you updated every item. For that matter, you could use Find() and just return false and it will keep running over all items.



private void button5_Click(object sender, EventArgs e)

{

List<Customer> l = new List<Customer>();

l.Add(new Customer("wjs"));

l.Add(new Customer("john"));

l.Add(new Customer("sam"));

l.Add(new Customer("sara"));

l.FindAll(delegate(Customer c)

{

c.Name = c.Name + " doe";

return true;

});

foreach(Customer c in l)

{

Console.WriteLine(c.Name);

}



}


--
William Stacey [MVP]

| I've finally had the time to make use or predicates and convert a bunch of
| ugly loops over to predicates. SO much cleaner.
| Anyway, my question is if there are plans (or maybe already existing) to add
| List<> function that would call a predicate on every item like a process.
|
| For example:
| public static Predicate<MyObject> ApplyTax(float taxRate)
| {
| return delegate(MyObject item)
| {
| item.Tax = taxRate;
| };
| }
|
| List<MyObject> objects = new List<MyObject>();
| // code to add a ton of objects to the list
|
| ojects.ProcessAll( ApplyTax(7.75) );
|
|
|
| Is there anything like that already existing? I haven't seen anything, but
| maybe I'm just dense.
| Thanks for reading,
| Steve
|
|
 
My experience of predicates in C++ and the STL is that they usually make the
code much harder to read and are not actually used very often.

When I first got into STL I wanted to try them out so I wrote quite a lot of
function objects into my code - At code review nobody understood it - I
don't use them anymore except for the very rare case when just one of the
STL ones will do the job (without using binders).

Also template methods with predicate classes using inline methods (NOT
function pointers) can easily be optimized into inline loops in C++. The
same is not generally possible in C#.
 
William said:
Cool thing about methods that take a predicate delegate is that you can do what ever you want.

For example, the FindAll method will run your delegate over every item, so you can update each item and you may not even care about the return as you know you updated every item. For that matter, you could use Find() and just return false and it will keep running over all items.

It might be possible, but it's going to explode the brain of the next
person to look at your code. If you want to say "for each item do this
action", then maybe use ForEach and Action<T>, rather than using
FindAll to do something other than finding?
 
That is better. Here ya go:



List<Customer> l = new List<Customer>();

l.Add(new Customer("wjs"));

l.Add(new Customer("john"));

l.Add(new Customer("sam"));

l.Add(new Customer("sara"));

l.ForEach(delegate(Customer c)

{

c.Name = c.Name + " doe";

Console.WriteLine(c.Name);

});


--
William Stacey [MVP]

|
| William Stacey [MVP] wrote:
| > Cool thing about methods that take a predicate delegate is that you can do what ever you want.
| >
| > For example, the FindAll method will run your delegate over every item, so you can update each item and you may not even care about the return as you know you updated every item. For that matter, you could use Find() and just return false and it will keep running over all items.
|
| It might be possible, but it's going to explode the brain of the next
| person to look at your code. If you want to say "for each item do this
| action", then maybe use ForEach and Action<T>, rather than using
| FindAll to do something other than finding?
|
|
| --
| Larry Lard
| Replies to group please
|
 
William said:
That is better. Here ya go:



List<Customer> l = new List<Customer>();

l.Add(new Customer("wjs"));

l.Add(new Customer("john"));

l.Add(new Customer("sam"));

l.Add(new Customer("sara"));

l.ForEach(delegate(Customer c)

{

c.Name = c.Name + " doe";

Console.WriteLine(c.Name);

});

That kind of code is only useful when the delegate is passed in from
another method, e.g. a validation delegate or what have you. The
example you presented is IMHO not that useful. I mean, what's against:

List<Customer> l = new List<Customer>();
l.Add(new Customer("wjs"));
l.Add(new Customer("john"));
l.Add(new Customer("sam"));
l.Add(new Customer("sara"));
foreach(Customer c in l)
{
c.Name = c.Name + " doe";
Console.WriteLine(c.Name);

};

It's faster too :)

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
 
| That kind of code is only useful when the delegate is passed in from
| another method, e.g. a validation delegate or what have you. The
| example you presented is IMHO not that useful. I mean, what's against:
|
| List<Customer> l = new List<Customer>();
| l.Add(new Customer("wjs"));
| l.Add(new Customer("john"));
| l.Add(new Customer("sam"));
| l.Add(new Customer("sara"));
| foreach(Customer c in l)
| {
| c.Name = c.Name + " doe";
| Console.WriteLine(c.Name);
|
| };
|
| It's faster too :)

True. Just trying to answer the OPs question. There is probably a reason he
wanted the info. If looking for faster, then a for() loop is even faster
then foreach.
 
Thanks all for your input. Answered my question and raised some good isues
as well!

Thanks again,
Steve
 
Back
Top