views:

259

answers:

2

I have a class that builds a url with query string parameters and so on. The class has a method: Url() which returns the complete url composed from the class properties and another method: UrlNew() which allows passing a predicate as parameter for the replacement of the value of one of the properties and THEN Returns the modified URL. Now, I need to modify this function to use TWO parameters, both predicates. How do I do that? I tried modifying the method's parameters as a List of predicates but I probably am not doing something right:

My OLD UrlNew() method looked like this:

public static string Url() (Action<LGUrlBuilder> predicate)
    {
        var instance = new LGUrlBuilder();
        if (predicate != null) predicate(instance);
        return instance.BuildUrl();
    }

My NEW UrlNew() method looks like this:

public static string UrlNew(List<Action<LGUrlBuilder>> predicateList)
    {
        var instance = new LGUrlBuilder();
        if (predicateList != null && predicateList.Count > 0)
        {
            foreach (Action<LGUrlBuilder> predicate in predicateList)
            {
                if (predicate != null) predicate(instance);
            }
        }

        return instance.BuildUrl();
    }

This compiles just fine but when I run it, using it in ASPX gives me this error:

CS1660: Cannot convert lambda expression to type 'System.Collections.Generic.List<System.Action<public_site.Library.LG.LGUrlBuilder>>' because it is not a delegate type

I am a C# beginner and I am sure I am doing something completely wrong. Any advice would help. Thanks!

+4  A: 

Don't modify the function itself. Modify the method call like this:

UrlNew(x => { func1(x); func2(x); });

But if you really want to take arbitrary number of delegate instances as arguments, try modifying it like:

public static void UrlNew(params Action<LGUrlBuilder>[] list) {
    // ... do what you're already doing in the second snippet ...
}

You can call it like:

UrlNew(x => firstthing(), x => secondthing(x), thirdthing);

Side note: An Action<T> is not called a predicate. A predicate returns a boolean value.

Mehrdad Afshari
thanks, I was about to ask specifically how to implement that, trying it now...
Cristi Cotovan
This totally worked! Thanks a lot. Yes, I really wanted to have an arbitrary number of instances in the arguments list.
Cristi Cotovan
A: 

How about using the overloaded Action<T1,T2> delegate which accepts 2 parameters. If you are looking to use a predicate instead which expects a boolean return value then use Func<T1,T2,bool> instead.

Abhijeet Patel
I kind of like the side effect of not being constrained to just two parameters.
Cristi Cotovan