Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对不同类型使用相同名称调用方法_C# - Fatal编程技术网

C# 对不同类型使用相同名称调用方法

C# 对不同类型使用相同名称调用方法,c#,C#,我使用的是旧的(.NET 1)API,无法更改。API没有接口。我有一个基类(Pet)和具体的类(Cat,Parrot),它们基本上具有“相同”的方法(GetLegs())。我希望我的helper类“abtract away”,并使用实例的类型调用该方法。我想避免反思 我的尝试有我的打开类型。这是否合理的做法?我是否应该(在“理论”层面上)担心类型过于笼统 namespace TheApi { public class Pet { } public class

我使用的是旧的(.NET 1)API,无法更改。API没有接口。我有一个基类(
Pet
)和具体的类(
Cat
Parrot
),它们基本上具有“相同”的方法(
GetLegs()
)。我希望我的helper类“abtract away”,并使用实例的类型调用该方法。我想避免反思

我的尝试有我的打开类型。这是否合理的做法?我是否应该(在“理论”层面上)担心
类型
过于笼统

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));
        }
    }
}
namespace-TheApi
{
公营宠物
{
}
公营猫:宠物
{
公共字符串[]GetLegs()=>
新[]{“左前”、“右前”、“左后”、“右后”};
}
公营鹦鹉:宠物
{
公共字符串[]GetLegs()=>
新[]{“左”、“右”};
}
}
名称空间MyApp
{
使用制度;
使用System.Collections.Generic;
使用NUnit.Framework;
使用API;
公共静态类助手
{
公共静态字符串[]GetLegsFor(宠物)
{
返回MapTypeToGetter[pet.GetType()](pet);
}
专用静态字典MapTypeToGetter=>
新词典
{
[typeof(Cat)]=p=>((Cat)p).GetLegs(),
[typeof(Parrot)]=p=>((Parrot)p).GetLegs()
};
}
公开课考试
{
[测试]
公开无效测试()
{
宠物鸟=新鹦鹉();
var legs=Helper.GetLegsFor(bird);
var expectedLegs=new[]{“Left”,“Right”};
断言(legs,Is.EqualTo(expectedLegs));
}
}
}
我希望我的helper类“abtract away”,并使用实例的类型调用该方法。我想避免反思

我根本不会编写帮助器类。我将编写一个扩展方法:

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();
我希望我的helper类“abtract away”,并使用实例的类型调用该方法。我想避免反思

我根本不会编写帮助器类。我将编写一个扩展方法:

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();

你应该有一个接口-
IHaveLegs
。为什么不在
Pet
?@DanielA.White上使用扩展方法呢?OP说:我正在使用一个旧的(.NET 1)API,我无法更改。API没有接口。
Cat
Parrot
是由您实现的吗?API以何种方式对您的其余代码施加任何约束?您应该有一个接口-
IHaveLegs
。为什么不简单地在
Pet
上使用扩展方法?@DanielA.White OP说:我正在使用一个旧的(.NET 1)我不能改变。API没有接口。
Cat
Parrot
是由您实现的吗?API以何种方式对您的其余代码施加任何约束?嗨,Eric,我正在仔细研究OOP概念。创建扩展方法v的优点是什么。接口。假设我想创建一个
蠕虫
类,它可以是
宠物
,但没有腿。使用一个界面,这样我就可以选择哪只宠物有腿或没有腿,这不是更好吗?谢谢。@Zuzlx:那当然更好了。问题的前提是不可能使用接口。重读问题的前两句。扩展方法是语法糖,我可以把它加到我的句子中。但是你的方法真的和我的不同吗,比如说,我们都打开了类型,不是吗?嗨,埃里克,我在试着思考OOP的概念。创建扩展方法v的优点是什么。接口。假设我想创建一个
蠕虫
类,它可以是
宠物
,但没有腿。使用一个界面,这样我就可以选择哪只宠物有腿或没有腿,这不是更好吗?谢谢。@Zuzlx:那当然更好了。问题的前提是不可能使用接口。重读问题的前两句。扩展方法是语法糖,我可以把它加到我的句子中。但是你的方法真的和我的不同吗,即我们都打开类型,不是吗?