C # syntax, assigning a delegate to a class and calling later

I have a bit of confusion with this C # syntax. I am trying to assign an arbitrary delegate to a class.

I have delegates defined as

delegate string stringCB(string s);
delegate int intCB(int i);

      

I have a class

class run_by_name {
    public string name {get;set;}
    public Delegate method {get;set;}
};

      

And I am trying to instantiate

 run_by_name myfuc = new run_by_name(){
     name = "my name",
     method = new stringCB(string s) {
         return " testing " + s;
     };
 };

      

I really don't understand how to assign a delegate when there is a return type. Also I'm not sure what how to syntactically call this method later .

Why am I doing this? Well, I just write the code that follows the pattern I use in JS to handle events, I just create an "object". I can assign arbitrary functions to a generic event handler that is created rather than defined. (important)

Also, alternatives to using delegates are welcome. :)

EDIT: how can I use it later
I don't have this, but I'm pretty sure I will.

List<run_by_name> callbacks = new List<run_by_name>();
/* lets say this is initialized and filled at this point */

public object FindAndRunCallback(string Name, object input) {
    foreach(var cb in callbacks) {
        if( cb.name == Name )
            return cb.method(input);
    }
    return null;
}

      

+3


source to share


2 answers


Here is the syntax required for your current code to work:

 method = new stringCB((string s) =>  {
     return " testing " + s;
 })

      

Or, using lambda expressions:

 method = new stringCB(s =>" testing " + s)

      



You can call the method later like this:

string result = (string) myfuc.method.DynamicInvoke("hello");

      

Without knowing more about your use case, it's hard to recommend other approaches, but I would recommend at least looking into the following:

  • Events. Your description sounds very close to the general pattern for events and event handlers in C #. Your event defines the type of delegate that is used to handle it, and code elsewhere can subscribe to this event using methods that match the type of the delegate. By convention, people usually pass the sender object

    as the first parameter and some are strongly typed EventArgs

    , so subscribers don't have to guess what data will be available when the event occurs. Options
  • Func<>

    and Action<>

    that since C # has become a more functional language, programmers refused to use user-defined types, and delegates used the granted options Func<>

    and Action<>

    . Since the arguments are strongly typed, you get most of the benefits of a compiled language, but use a little "duck typing" for the actual function you are passing through.

    For example, you can give your class a generic type depending on what types you expect from your delegate:

    class run_by_name<T> {
        public string name {get;set;}
        public Func<T, T> method {get;set;}
    };
    
          

    Then use it:

    var myfuc = new run_by_name<string>{
        name = "my name",
        method = s =>" testing " + s
    };
    
    string result = myfuc.method("hello");
    
          

  • dynamic

    : This keyword allows you to perform late binding actions on any object. You lose the benefits of a compiled language, but it improves interoperability with more dynamic languages. For example, an object can be instantiated via JSON and you can access properties on it without declaring a special type for that object, as you can in Javascript.

    For example, if you changed your ad method

    to this:

    public dynamic method {get;set;}
    
          

    Then you could just say:

    string result = myfuc.method("hello");
    
          

+3


source


You have a choice of secrets. the constructor strinCB

expects a method that takes a string parameter and returns a string. If you have an existing method, you can pass its name to the constructor, or you can create an anonymous wither method using the delegation syntax like this:

method = new stringCB(delegate(string s)
            {
                return " testing " + s;
            })

      

Or using a lambda expression:

method = new stringCB(s =>
            {
                return " testing " + s;
            })

      

Then you can call it like this: myfuc.method.DynamicInvoke(YourParameter);



Usually calling a delegate method is pretty simple:

Func<int, int, int> sum = (x, y) => x + y;

Console.WriteLine(sum(2,3)); // with the name of delegate

Console.WriteLine(sum.Invoke(2,3)); // or using Invoke method

      

But in this case, you need to use DynamicInvoke

because the type of your property Delegate

.

In addition, .NET Framework

it has some nice built-in types of delegates, such as Func

, Action

and Predicate

etc. You can use them instead of creating your own delegate as long as they suit your needs. For example, in this case, you can use Func<string,string>

instead stringCB

.

+2


source







All Articles