how to improve this method using polymorphism+overloading so as to reduce IS (type check)?

后端 未结 2 1215
栀梦
栀梦 2020-12-10 17:23

For example

BaseClass MyBase()
{
    public int Add(BaseClass next)
    {
        if (this is InheritedA && next is InheritedA)
            return 1;         


        
2条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-10 18:21

    As was suggested in the comments, if you are able to assign a constant value to each derived, then you can build a much cleaner implementation than I'm describing here by just having a virtual property named Value or similar that is used to for the addition.

    Assuming that isn't an option, you may wish to consider pre-computing the results at the base class level to describe the values that you're assigning for each combination. This can break down and become error prone and tedious as the set of classes grows, so I would suggest only considering this if you expect a very small set to maintain.

    In my rudimentary example, I used a dictionary to hold the set and hard-coded the combinations. From your comment, it appears that none of the basic rules of arithmetic apply, so I've left them out as constraints here. If the result value has no actual meaning and you're just incrementing it, you could consider building the result set using reflection to pull the derived classes and considering each combination.

    public class BaseClass
    {
      private static readonly Dictionary addResults = new Dictionary();
    
      static BaseClass()
      {
        addResults.Add(CreateKey(typeof(ChildA), typeof(ChildA)), 1);
        addResults.Add(CreateKey(typeof(ChildA), typeof(ChildB)), 2);
        addResults.Add(CreateKey(typeof(ChildB), typeof(ChildA)), 3);
        addResults.Add(CreateKey(typeof(ChildB), typeof(ChildB)), 4);
      }
    
      public static int CreateKey(Type a, Type b)
      {
        return (String.Concat(a.Name, b.Name).GetHashCode());
      }
    
      public int Add(BaseClass next)
      {
        var result = default(int);
    
        if (!addResults.TryGetValue(CreateKey(this.GetType(), next.GetType()), out result))
        {
          throw new ArgumentOutOfRangeException("Unknown operand combination");
        }
    
        return result;
      }
    }
    
    public class ChildA : BaseClass {}
    public class ChildB : BaseClass {}
    

提交回复
热议问题