0

I am writing an HTTP wrapper class object in C# and I would like to give the main method the ability to receive a function as a parameter and then execute it on the source HTML returned by the POST/GET.

For example I may want to pass a function that checks the headers for a cookie and only returns true if it's found OR pass a regular expression function that checks the source for a piece of content.

I know in PHP or JS I could easily just pass functions as parameters but I am not sure on how to go about it without creating delegates that match the functions I want to use.

I would like the code to be as "generic" as possible so that it could receive any function e.g Pseudocode would be like

public bool MakeHTTPRequest(string url, object possiblefunction)
{

   make HTTP request

   if status == 200
   {

    string response = getresponse

    if(object is function){

        call object
    }
  }
}

So the function may OR may NOT be passed in, or I may set a global property with it. Then I need to check IF a function exists and execute it if it does.

The function could be ANYTHING and I want to future proof the code so it can handle any kind of function in the future that maybe passed to it.

Any help would be much appreciated.

Thanks

3
  • Use Action, Action<T>, etc.... Commented Aug 30, 2013 at 12:39
  • Or if the function returns something: Func< TResult >, Func<T, TResult>, etc. - the thing is, actions or functions might need parameters (the Ts here). You won't be able to just "call" an action or function without parameters if it needs them. Commented Aug 30, 2013 at 12:41
  • It's commonly bad practice to use the datatype object in the method signature. You can do it but you're going to need to implement a lot of exception handling. Commented Aug 30, 2013 at 12:48

2 Answers 2

1

Use either Func or Action (or Predicate as mentioned by DavidN) to specify the contract of delegates passed as a parameter into your MakeHTTPRequest method.

public bool MakeHTTPRequest(string url, Action possiblefunction)
{

   make HTTP request

   if status == 200
   {

    string response = getresponse

    if(possiblefunction != null){

        possiblefunction();
    }
  }
}

If your "function" returns a value/result then use Func instead..(where T is the expected return type)...e.g. Func<int>.

If your "function" expects parameters then specify the expected parameter types. So here are some examples:

Func<string,float,int> - a delegate which expects string and float parameters and returns an int result

Action - a delegate that takes no parameters, and doesn't return a value

Action<string,float> - a delegate that doesn't return a value (void), and expects a string and float as parameters.

If you're trying to pass back the "response" to the possiblefunction then do something like this.

public bool MakeHTTPRequest(string url, Action<string> possiblefunction)
{

   make HTTP request

   if status == 200
   {

    string response = getresponse

    if(possiblefunction != null){

        possiblefunction(response);
    }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

If it is MakeHTTPRequest(string url, object possiblefunction) then you can test var action = possiblefunction as Action; if (action != null) { action(); }
0

Based on the examples you've given, it seems that what you really want is to pass in a set of validators to determine if the HTTP response meets certain criteria. This seems to be further corroborated by the fact that your method is returning bool.

A Predicate<T>, or actually a set of Predicates, should encapsulate criteria rules that you pass in to determine whether the request is valid or not.

The signature for a Predicate<T> is bool Predicate<T>(T t) - meaning that it takes in some type and produces a bool

Using an array of predicates, and making sure they all pass, seems to be a pretty future-proof way for what you want to do

public bool MakeHTTPRequest(string url, params Predicate<WebResponse>[] validators)
{    
   // make HTTP requrest

   var request = HttpWebRequest.Create(url);
   var response = (HttpWebResponse)request.GetResponse();

   if (response.StatusCode == HttpStatusCode.OK){
        foreach(var validator in validators)
            if (!validator(response))
                return false;
   }

    return true;    
}

The trick is that the params keyword allows you to call the method passing in [0..any number] of values for the params, so all of the following invocations would work:

MakeHTTPRequest("http://stackoverflow.com");
MakeHTTPRequest("http://stackoverflow.com", r => r.Headers.AllKeys.Contains("CookieHeader"));
MakeHTTPRequest("http://stackoverflow.com", r => r.Headers.AllKeys.Contains("CookieHeader"), r => r.ContentLength < 10000);

2 Comments

Wicked, just what I wanted. Yes you are right. I want to pass in any number of functions that validate the response yet I don't know how many or what they might contain at design time. An array of functions/validators is just what I need. Thanks!
quick question, I notice most of those validators are simple boolean tests. What if I wanted to pass in as a validator a function that did multiple checks, ORS, or complex checking not just a simple IF A AND B AND C. So a function that checks multiple criteria and if true, then further checks are done or not done before returning true/false. So something a bit more complex than is the length of content < 1000 or does a cookie exist etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.