C#: implicit operator and extension methods

前端 未结 3 2069
暗喜
暗喜 2021-01-11 11:39

I am trying to create a PredicateBuilder class which wraps an Expression> and provides some methods to easily bu

相关标签:
3条回答
  • 2021-01-11 12:03

    As Anton says, if you put the extension methods directly on Expression<Func<...>> it would probably work.

    More explanation... nothing particularly clever, but the idea would be that you don't have a PredicateBuilder class that you create instances of. Instead you just have purely static building blocks:

    public static class Predicates
    {
        public static Expression<Func<T, bool>> True<T>()
        {
            return x => true;
        }
    
        public static Expression<Func<T, bool>> False<T>()
        {
            return x => false;
        }
    
        public static Expression<Func<T, bool>> And<T>(
            this Expression<Func<T, bool>> left,
            Expression<Func<T, bool>> right)
        {
            return ... // returns equivalent of (left && right)
        }
    }
    

    Those two functions True and False play the role of your PredicateBuilder(bool) constructor, and you'd presumably have similar ones for primitive comparisons and so on, and then operators like And would let you plug two expressions together.

    However, then you lose the ability to use operator symbols, which you could have used with your wrapper object, and instead you have to use method names. I've been playing around with the same kind of approaches, and the thing I always come back to is that I want to be able to define extension operators. The C# team apparently considered these for 3.0 (along with extension properties) but they were lower priority because they didn't play a part in the overall aims of Linq.

    0 讨论(0)
  • 2021-01-11 12:05

    This is not specific to extension methods. C# won't implicitly cast an object to another type unless there is a clue about the target type. Assume the following:

    class A {
        public static implicit operator B(A obj) { ... }
        public static implicit operator C(A obj) { ... }
    }
    
    class B {
        public void Foo() { ... }
    }
    
    class C {
        public void Foo() { ... }
    }
    

    Which method would you expect to be called in the following statement?

    new A().Foo(); // B.Foo? C.Foo? 
    
    0 讨论(0)
  • 2021-01-11 12:21

    No, you haven't, but C# compiler's type deduction isn't powerful enough to understand your code, and in particular, it doesn't look at implicit operators. You'll have to stick with Expression<Func<T,bool>> — why not have extension methods like Or, And directly on expressions?

    0 讨论(0)
提交回复
热议问题