开发者

Functors () overloading for classes

I do not think this is possible and curious if it is or why it is not:

class A
{

}

I would like to treat instances of A as functions such as

A a = new A();

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

This is to treat classes as functions for special cases when it is useful to do so. For example, I'm essentially wrapping a Func object but would love to treat an instance of such a class to act as the Func object itself. This way I don't have to have a "dummy" function to call in the class.


    public class Condition
    {
        protected Func<bool> Eval { get; set; }
        protected bool Or 开发者_如何学C= 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();
        }
    }

To initiate the Computation I call the member (), e.g., cblock.(). It would look much nicer if I could call it as cblock(). Effectively a ConditionBlock is a compound function. Would be nice to be able to treat it as such. Using _() is quite ugly as is renaming it to anything else such as cblock.fire(), cblock.eval(), etc...


You can't overload the () operator in C#, but that's what delegates are for; they do what you describe, e.g.:

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


You could always just provide an indexer (or overloaded indexers).

The only difference would be square brackets.


You could provide implicit conversion to a delegate type and use the delegate type instead.

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


I don't clearly understand what you are trying to achieve? Well, it seems that you believe that some approaches are ugly and you are trying to make your code nice. Anyway, In your case you can use an implicit operator instead if Eval method:

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

the usage will be like this:

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

Hope this helps!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜