Может ли метод быть переопределен лямбда-функцией - PullRequest
3 голосов
/ 09 июля 2009

Есть ли способ переопределить метод класса с помощью лямбда-функции?

Например, с определением класса

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

Есть ли что делать:

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

Ответы [ 6 ]

6 голосов
/ 09 июля 2009

Крис прав, что методы нельзя использовать как переменные. Тем не менее, вы можете сделать что-то вроде этого:

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

Чтобы разрешить переопределение действия:

MyClass myObj = new MyClass();
myObj.MyAction = (x) => { Console.WriteLine(x); };
5 голосов
/ 09 июля 2009

Нет. Однако, если вы вначале объявите метод как лямбду, вы можете установить его, хотя я постараюсь сделать это во время инициализации.

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

    public readonly Action<int> MyMethod;
}

Это, однако, не может реализовать интерфейс с объявленным MyMethod, если в интерфейсе не указано лямбда-свойство.

F # имеет выражения объекта, которые позволяют вам составлять объект из лямбд. Я надеюсь, что в какой-то момент это часть c #.

0 голосов
/ 09 июля 2009

В зависимости от того, что вы хотите сделать, есть много способов решить эту проблему.

Хорошей отправной точкой является создание делегируемого (например, Action) свойства, которое можно получить и установить. После этого вы можете иметь метод, который делегирует это свойство действия, или просто вызывать его непосредственно в клиентском коде. Это открывает множество других опций, таких как частная установка свойства action (возможно, предоставление конструктора для его установки) и т. Д.

* 1005 Е.Г. *

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; }
}
0 голосов
/ 09 июля 2009

Не напрямую, но с небольшим кодом это выполнимо.

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);
    }
}

тогда вы могли бы иметь код

Derived d = new Derived();
int resultBase = d.Convert("1234");
d.ConvertFunc = (o) => { return -1 * Convert.ToInt32(o); };
int resultCustom = d.Convert("1234");
0 голосов
/ 09 июля 2009

Вы можете написать этот код:

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

Если вы определите MyClass таким образом:

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

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

Но это не должно быть слишком удивительно.

0 голосов
/ 09 июля 2009

Нет. Методы нельзя использовать как переменные.

Если бы вы использовали JavaScript, то да, вы могли бы сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...