tags:

views:

143

answers:

6

Is there any way to override a class method with a lambda function?

For example with a class definition of

class MyClass {  
    public virtual void MyMethod(int x) {
        throw new NotImplementedException();
    }
}

Is there anyway to do:

MyClass myObj = new MyClass();
myObj.MyMethod = (x) => { Console.WriteLine(x); };
A: 

No. Methods cannot be used like variables.

If you were using JavaScript, then yes, you could do that.

Chris Thompson
+4  A: 

No. However if you declare the method as a lambda in the first place, you can set it, though I would try to do that at initialization time.

class MyClass {  
    public MyClass(Action<int> myMethod)
    {
        this.MyMethod = myMethod ?? x => { };
    }

    public readonly Action<int> MyMethod;
}

This however cannot implement an interface that has a MyMethod declared, unless the interface specifies a lambda property.

F# has object expressions, which allow you to compose an object out of lambdas. I hope at some point this is part of c#.

eulerfx
+6  A: 

Chris is right that methods cannot be used like variables. However, you could do something like this:

class MyClass {
    public Action<int> MyAction = x => { throw new NotImplementedException() };
}

To allow the action to be overridden:

MyClass myObj = new MyClass();
myObj.MyAction = (x) => { Console.WriteLine(x); };
dahlbyk
A: 

You can write this code:

MyClass myObj = new MyClass();
myObj.TheAction = x => Console.WriteLine(x);
myObj.DoAction(3);

If you define MyClass in this way:

class MyClass
{
  public Action<int> TheAction {get;set;}

  public void DoAction(int x)
  {
    if (TheAction != null)
    {
      TheAction(x);
    }
  }
}

But that shouldn't be too surprising.

David B
A: 

Not directly, but with a little code it's doable.

public class MyBase
{
    public virtual int Convert(string s)
    {
        return System.Convert.ToInt32(s);
    }
}

public class Derived : MyBase
{
    public Func<string, int> ConvertFunc { get; set; }

    public override int Convert(string s)
    {
        if (ConvertFunc != null)
            return ConvertFunc(s);

        return base.Convert(s);
    }
}

then you could have code

Derived d = new Derived();
int resultBase = d.Convert("1234");
d.ConvertFunc = (o) => { return -1 * Convert.ToInt32(o); };
int resultCustom = d.Convert("1234");
Robert Paulson
I wouldn't really have ConvertFunc as a public property. The above code is illustration only.
Robert Paulson
A: 

Depending on what you want to do, there are many ways to solve this problem.

A good starting point is to make a delegate (e.g. Action) property that is gettable and settable. You can then have a method which delegates to that action property, or simply call it directly in client code. This opens up a lot of other options, such as making the action property private settable (perhaps providing a constructor to set it), etc.

E.g.

class Program
{
    static void Main(string[] args)
    {
        Foo myfoo = new Foo();
        myfoo.MethodCall();

        myfoo.DelegateAction = () => Console.WriteLine("Do something.");
        myfoo.MethodCall();
        myfoo.DelegateAction();
    }
}

public class Foo
{
    public void MethodCall()
    {
        if (this.DelegateAction != null)
        {
            this.DelegateAction();
        }
    }

    public Action DelegateAction { get; set; }
}
Wedge