为不同类型调用具有相同名称的方法

时间:2017-01-06 16:56:30

标签: c#

我正在使用旧的(.NET 1)API,我无法改变。 API没有接口。我有一个基类(Pet),其具有基本上“相同”方法(Cat)的具体类(ParrotGetLegs())。我希望我的帮助类“消除”并使用实例的类型调用方法。我想避免反思。

我尝试打开了类型。这是一种合理的方法吗?我应该担心(在'理论层面上)Type过于笼统吗?

namespace TheApi
{
    public class Pet
    {
    }

    public class Cat : Pet
    {
        public string[] GetLegs() =>
            new[] { "Front left", "Front right", "Back left", "Back right" };
    }

    public class Parrot : Pet
    {
        public string[] GetLegs() =>
            new[] { "Left", "Right" };
    }
}

namespace MyApp
{
    using System;
    using System.Collections.Generic;
    using NUnit.Framework;
    using TheApi;
    public static class Helper
    {
        public static string[] GetLegsFor(Pet pet)
        {
            return MapTypeToGetter[pet.GetType()](pet);
        }

        private static Dictionary<Type, Func<Pet, string[]>> MapTypeToGetter =>
            new Dictionary<Type, Func<Pet, string[]>>
            {
                [typeof(Cat)] = p => ((Cat)p).GetLegs(),
                [typeof(Parrot)] = p => ((Parrot)p).GetLegs()
            };
    }

    public class Tests
    {
        [Test]
        public void Test()
        {
            Pet bird = new Parrot();
            var legs = Helper.GetLegsFor(bird);

            var expectedLegs = new[] { "Left", "Right" };
            Assert.That(legs, Is.EqualTo(expectedLegs));
        }
    }
}

1 个答案:

答案 0 :(得分:2)

  

我希望我的帮助类“消除”并使用实例的类型调用方法。我想避免反思。

我根本不会写一个助手类。我写了一个扩展方法:

namespace PetesExtensions 
{
  public static class PetExtensions 
  {
    public static string[] GetLegs(this Pet pet)
    {
      if (pet == null) throw new ArgumentNullException("pet");
      if (pet is Cat) return ((Cat)pet).GetLegs();
      if (pet is Parrot) return ((Parrot)pet).GetLegs();
      throw new Exception(
        $"I don't know how to get the legs of a {pet.GetType().Name}. Contact Pete Moloy.");
    } 
  }
}

然后你可以说

using PetesExtensions;
...
Pet p = whatever;
string[] legs = p.GetLegs();