代码之家  ›  专栏  ›  技术社区  ›  Greg Beech

最接近的c等价于f匹配表达式?

  •  7
  • Greg Beech  · 技术社区  · 15 年前

    我的很多类都是由不同类型的知名但无序对象组成的容器,例如,容器可能看起来如下:

    public class Container
    {
        public A A { get; private set; }
        public B B { get; private set; }
        public C C { get; private set; }
    
        public bool StoreIfKnown(object o)
        {
            // TODO...
        }
    }
    

    所以如果 o 属于类型 A 它应该存储在 性质、类型 B B 财产等。

    在F中 StoreIfKnown 方法可以写如下(请原谅语法错误,我的f不太好,而且很粗糙):

    match o with
    | ?: A a -> A <- a; true
    | ?: B b -> B <- b; true
    | ?: C c -> C <- c; true
    | _ -> false
    

    但在c中,唯一的方法似乎是相当冗长的:

    if (o is A)
    {
        this.A = (A)o;
        return true;
    }
    
    if (o is B)
    {
        this.B = (B)o;
        return true;
    }
    
    // etc.
    
    return false;
    

    我可以用 as 关键字以避免更快但更详细的测试/转换模式。

    用C语言做这个有什么优雅的方法吗?

    5 回复  |  直到 8 年前
        1
  •  11
  •   Brian    15 年前

    o.Match<A>( a => { this.A = a; return true; } )
     .Match<B>( b => { this.B = b; return true; } )
     .Else( () => { return false; } )
    

    http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx

        2
  •  9
  •   Juliet    15 年前

    if (o is {DataType})
    {
        {Property} = ({DataType})o;
        return true;
    }
    

    public class Container
    {
        public A A { get; private set; }
        public B B { get; private set; }
        public C C { get; private set; }
    
        private bool TestProp<T>(object o, Action<T> f)
        {
            if (o is T)
                return false;
    
            f((T)o);
            return true;
        }
    
        public bool StoreIfKnown(object o)
        {
            return
                TestProp<A>(o, x => A = x) ||
                TestProp<B>(o, x => B = x) ||
                TestProp<C>(o, x => C = x) ||
                false;
        }
    }
    

        private bool TestProp<T>(T o, Action<T> f)
        {
            if (o == null)
                return false;
    
            f(o);
            return true;
        }
    
        public bool StoreIfKnown(object o)
        {
            return
                TestProp(o as A, x => A = x) ||
                TestProp(o as B, x => B = x) ||
                TestProp(o as C, x => C = x) ||
                false;
        }
    
        3
  •  8
  •   Community CDub    8 年前

    Brian's answer

    C IsActive true

    var stored = Match.Against(o)
        .When<A>().Then(a => { this.A = a; return true; })
        .When<B>().Then(b => { this.B = b; return true; })
        .When<C>(c => c.IsActive).Then(c => { this.C = c; return true; })
        .Otherwise(a => false);
    

        4
  •  2
  •   flq    15 年前
        5
  •  1
  •   Tomasz Maczyński    8 年前

    there is a limited support for pattern matching Visual Studio “15” Preview 4

    public class Container
    {
        public A A { get; private set; }
        public B B { get; private set; }
        public C C { get; private set; }
    
        public bool StoreIfKnown(object obj)
        {
            switch (obj)
            {
                case A a:
                    this.A = a
                    // I don't put "break" because I'm returning value from a method
                    return true;
                case B b:
                    this.B = b
                    return true;
                case C c:
                    this.C = c
                    return true;
                default:
                    WriteLine("<other>");
                    return false;
            }
        }
    }