模式匹配具有相同动作的多个案例

时间:2019-03-10 09:15:26

标签: .net-core polymorphism pattern-matching

您好,我有一个abstract类和2派生类。层次结构的性质使我处于两个derived成员共享一个公用property的不利位置但是超类没有它。 因此,尽管我有2个具有共同属性的派生类,但我需要在switch语句中进行模式匹配,这两种情况 AND 都对它们应用相同的 Action

public abstract class Base
{

}
public D1:Base{
   public long Value{get;set;}
   public void SetValue(long val){
        this.Value=val;
   }
}
public D2:Base
{
   public long Value{get;set;}
   public void SetValue(long val)
   { 
      this.Value=val;
   }
}

public void PaternMatch(Base base)
{
    long val=5;
    switch(base)
    {
     case D1 d1:
     case D2 d2:
     //how can i say something like apply `SetValue regardless if its d1 or d2?
     d1.SetValue(val)?
     break;

}

更新,当有多个具有相同动作的案例时,有没有能让我获得类型的构造?

case string:
case int:
case double:
 Console.WriteLine("the option that matched was:"+[ option name of or value  ]`);

在上述情况下,我可以知道string匹配还是int?或至少获得匹配的索引? 0-string1-int2 -double

1 个答案:

答案 0 :(得分:1)

public class Program
    {
        public static void Main(string[] args)
        {

            var d1 = new D1();
            PatternMatch(d1);

            Debug.Assert(d1.Value.Equals(5));
            Console.WriteLine(d1.Value);

            var d2 = new D2();
            PatternMatch(d2);
            Debug.Assert(d2.Value.Equals(5));
            Console.WriteLine(d2.Value);

            var d3 = new D3();
            PatternMatch(d3);
            Debug.Assert(d3.Value.Equals(105));
            Console.WriteLine(d3.Value);

            Console.ReadKey();
        }

        public static void PatternMatch(BaseD baseD)
        {
            long val = 5;
            switch (baseD)
            {
                // first case for self class, then check is d1 or d2... 
                case BaseD @base when @base is D1 || @base is D2:
                    // then, cause base does not implement SetValue method, we need to cast to D1 or to D2 and invoke SetValue(val);
                    switch (@base)
                    {
                        case D1 d1:
                            d1.SetValue(val);
                            break;
                        case D2 d2:
                            d2.SetValue(val);
                            break;
                    }

                    break;
                case D3 d3:
                    d3.SetValue(val);
                    break;

            }
        }
    }

    public abstract class BaseD
    {

    }

    public class D1 : BaseD
    {
        public long Value { get; private set; }

        public void SetValue(long val)
        {
            this.Value = val;
        }
    }

    public class D2 : BaseD
    {
        public long Value { get; private set; }

        public void SetValue(long val)
        {
            this.Value = val;
        }
    }

    public class D3 : BaseD
    {
        public long Value { get; private set; }

        public void SetValue(long val)
        {
            this.Value = val + 100;
        }
    }