2011-02-01 4 views
4

Python имеет этот волшебный метод __call__, который вызывается, когда объект вызывается как функция. Поддерживает ли C# что-то подобное?Поддерживает ли C# метод __call__?


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

+0

+1 Удивительный вопрос. – ClosureCowboy

ответ

4

кланяюсь Саймон Свенссон - который показывает способ сделать это, если вы унаследовали от DynamicObject - для более тесной вперед, не динамической точки зрения: не

Извините, но нет - но есть типы объектов, которые могут быть вызванными - например, делегатами.

Func<int, int> myDelagate = x=>x*2; 
int four = myDelagate(2) 

Существует свойство по умолчанию, хотя - что должен иметь по крайней мере один параметр и его доступ выглядит доступа к массиву:

class Test1 
{ 
    public int this[int i, int j] 
    { 
     get { return i * j; } 
    } 
} 

Calling

 Test1 test1 = new Test1(); 
     int six = test1[2, 3]; 

Затем вы можете сделать некоторые действительно глупые вещи с такими делегатами:

class Test2 // I am not saying that this is a good idea. 
{ 
    private int MyFunc(int z, int i) 
    { 
    return z * i; 
    } 
    public Func<int, int> this[int i] { get { return x => MyFunc(x, i); } } 
} 

Тогда называя это выглядит странно, как это:

 Test2 test = new Test2(); 
     test[2](2); // this is quite silly - don't use this..... 
3

Это было бы сродни перегрузки оператора вызова функции (как это возможно в C++). К сожалению, это не то, что поддерживается в C#. Единственными объектами, которые можно назвать похожими методами, являются экземпляры делегатов.

+0

Я бы предпочел, что, если не сказать, к счастью, вы не можете сделать это на C#. Надеюсь, я не слишком схожу с ума. :) – Neil

5

Несомненно, если вы наследуете от DynamicObject. Я думаю, что вы после TryInvoke, который выполняет на obj(...), но есть несколько другой метод можно переопределить для обработки литья, доступ индекс (obj[idx]), вызов метода, свойство вызовы и т.д.

using System; 
using System.Diagnostics; 
using System.Dynamic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication { 
    public static class ConsoleApp { 
     public static void Main() { 
      dynamic x = new MyDynamicObject(); 
      var result = x("awe", "some"); 

      Debug.Assert(result == "awesome"); 
     } 
    } 

    public class MyDynamicObject : DynamicObject { 
     public override Boolean TryInvoke(InvokeBinder binder, Object[] args, out Object result) { 
      result = args.Aggregate(new StringBuilder(), (builder, item) => builder.Append(item), builder => builder.ToString()); 
      return true; 
     } 
    } 
} 
+0

+1 Ничего себе! - вот огромная сила динамичности. Я, вероятно, никогда не буду использовать это, но это хорошо знать .... – Neil

+0

** + 1! ** Что за ад ?! Эпическая. – ClosureCowboy

Смежные вопросы