我正在使用旧的(.NET 1)API,我无法改变。 API没有接口。我有一个基类(Pet
),其具有基本上“相同”方法(Cat
)的具体类(Parrot
,GetLegs()
)。我希望我的帮助类“消除”并使用实例的类型调用方法。我想避免反思。
我尝试打开了类型。这是一种合理的方法吗?我应该担心(在'理论层面上)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));
}
}
}
答案 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();