Functors()为类重载

时间:2011-01-19 05:18:33

标签: c#

我不认为这是可能和好奇的,如果是或为什么不是:

class A
{

}

我想将A的实例视为

等函数
A a = new A();

a();
or
a(3);
etc...

这是为了在特殊情况下将类视为特殊情况的函数。例如,我实际上是包装一个Func对象,但是喜欢将这样一个类的实例视为Func对象本身。这样我就不必在类中调用“虚拟”函数。


    public class Condition
    {
        protected Func<bool> Eval { get; set; }
        protected bool Or = false;

        protected Condition() { }
        public Condition(Func<bool> f, bool Or = false) { Eval = f; this.Or = Or; }
        protected Func<bool> GetEval(Condition c) { return c.Eval; }
        protected bool GetOr(Condition c) { return c.Or; }

    }

    public class ConditionBlock : Condition
    {
        List<Condition> Conditions;

        public ConditionBlock() { Eval = _Eval; }

        public ConditionBlock(List<Condition> Conditions) : this() { this.Conditions = Conditions; }
        public ConditionBlock(Condition[] Conditions) : this() { this.Conditions = new List<Condition>(Conditions); }
        public void Add(Condition c) { if (Conditions == null) Conditions = new List<Condition>(); Conditions.Add(c); }

        private bool _Eval()
        {
            if (Conditions == null || Conditions.Count == 0) return true;

            bool ans = !GetOr(Conditions[0]);
            for (int i = 0; i < Conditions.Count; i++)
                ans = GetOr(Conditions[i]) ? ans | GetEval(Conditions[i])() : ans & GetEval(Conditions[i])();

            return ans;
        }

        public bool _()
        {
            return Eval();
        }
    }

要启动计算,我调用成员(),例如cblock。()。如果我可以将其称为cblock(),它看起来会更好。有效地,ConditionBlock是复合函数。很高兴能够像这样对待它。使用_()非常难看,因为将其重命名为其他任何内容,例如cblock.fire(),cblock.eval()等......

4 个答案:

答案 0 :(得分:2)

你不能在C#中重载()运算符,但这就是委托的用途;他们做你所描述的,例如:

class AccumulateToString
{
    private int sum;
    public string ToString(int val)
    { this.sum += val; return this.sum.ToString(); }
}
var fn = new Converter<int, string>(new AccumulateToString().ToString);
Console.WriteLine(fn(2)); // <-- called like a function but is an object w/ state

答案 1 :(得分:1)

您可以随时提供索引器(或重载的索引器)。

唯一的区别是方括号。

答案 2 :(得分:0)

您可以提供对委托类型的隐式转换,而改用委托类型。

public class Functor
{
    private int v;

    public Functor(int v)
    {
        this.v = v;
    }

    public static implicit operator Func<int, string>(Functor f)
    {
        return (x) => (x + f.v).ToString();
    }
}
...
internal void Foo()
{
    Func<int, string> f = new Functor(42);
    var result = f(1);
    ...
}

答案 3 :(得分:0)

我不清楚您要达到什么目标?好吧,您似乎似乎认为某些方法难看,并且您正在尝试使代码很好。无论如何,如果您使用Eval方法,可以使用隐式运算符代替:

public static implicit operator bool(ConditionBlock block)
{
    return true; //make the evaluation here
}

用法如下:

ConditionBlock cblock = new ConditionBlock();
// adjusting cblock
bool eval = cblock; // this is where the implicit does the magic of converting cblock to a boolean

希望这会有所帮助!