为了账号安全,请及时绑定邮箱和手机立即绑定

将接口转换为其实现

将接口转换为其实现

C#
红糖糍粑 2021-11-28 18:40:25
我有一个由更多存储附加信息的类实现的接口。而且我需要能够在不明确说明这是一个实现的情况下转换实现。public interface IAnimal{    string Name { get; set; }    Type GetType();}public class Dog : IAnimal{    public string Name { get; set; }    Type GetType() {return typeof(Dog);}    public int TimesBarked { get; set; }}public class Rhino : IAnimal{    public string Name { get; set; }    Type GetType() {return typeof(Rhino);}    public bool HasHorn { get; set; }}通过大部分代码,我可以毫无问题地使用接口,但在某些时候我需要将实现转换为原始类型。IAnimal animal = new Dog{    Name = "Ben",    TimesBarked = 30}// Doing stuff with Ben// In some other functionAnotherObject.SomeMethodThatNeedsToKnowType(animal) //Needs to be Converted before putting here我不知道我会得到哪个对象,所以我必须制作一些可以将任何东西转换为其原始类型的东西。不幸的是没有Convert.ChangeType(animal, animal.GetType())返回。我可以更改接口及其实现,但不能更改方法。object{Dog}Dog
查看完整描述

3 回答

?
开满天机

TA贡献1786条经验 获得超13个赞

不确定,你的最终游戏是什么。如果您不想使用 IS 和 AS,我可能会……无论如何:


using System;

using System.Windows.Forms;


namespace WindowsFormsApp1

{

    public partial class Form1 : Form

    {

        public interface IAnimal

        {

            string Name { get; set; }

            //Type GetType();

        }


        public class Dog : IAnimal

        {

            public string Name { get; set; }

            //new Type GetType() { return typeof(Dog); }

            public int TimesBarked { get; set; }

        }


        public class Rhino : IAnimal

        {

            public string Name { get; set; }

            //new Type GetType() { return typeof(Rhino); }

            public bool HasHorn { get; set; }

        }


        public Form1()

        {

            InitializeComponent();

        }


        private void button1_Click(object sender, EventArgs e)

        {

            IAnimal animal1 = new Dog { Name = "Ben", TimesBarked = 30 };

            IAnimal animal2 = new Rhino { Name = "James" };


            MessageBox.Show($"GetType : {animal1.GetType()}");


            PeopleWillTellYouToNotDoThis(animal1);

            PeopleWillTellYouToNotDoThis(animal2);

        }


        private void PeopleWillTellYouToNotDoThis(dynamic inAnimal)

        {

            MessageBox.Show($"GetType : {inAnimal.GetType()}");


            //The following works.  But, you should probably really use 'IS' to see if you have a RHINO or not

            try { MessageBox.Show($"HasHorn : {inAnimal.HasHorn}"); } catch { };

        }

    }

}


查看完整回答
反对 回复 2021-11-28
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

我不知道我会得到哪个对象,所以我必须制作一些可以将任何东西转换为原始类型的东西。


那时你打算用它做什么?由于您不知道类型,因此您不知道可以调用哪些方法等。这就是您的原始解决方案返回object.


您可以使用,dynamic但如果您尝试使用不存在的方法,则只会抛出。最接近的是简单is检查(C# 7 模式匹配为简洁起见):


if (animal is Dog dog) 

   //Do stuff with dog

else if (animal is Rhino rhino)

   // Do stuff with rhino

大胖免责声明:低头是一个巨大的危险信号。当你甚至不知道期望什么类型时,向下转型甚至更糟。您的设计几乎肯定需要重新思考。


查看完整回答
反对 回复 2021-11-28
?
UYOU

TA贡献1878条经验 获得超4个赞

全新的 C# 功能,“模式匹配”switch 语句(查看底部附近的Switch 语句文档)可以帮助您。


我一起完成了一个快速接口和几个实现它的类:


public interface IAnimal

{

    string Speak();

}


public class Cat : IAnimal

{

    public string Speak()

    {

        return "Meow";

    }

}


public class Dog : IAnimal

{

    public string Speak()

    {

        return "Woof";

    }

}

然后我创建了一个IAnimals的集合并使用一个switch语句来弄清楚什么是什么:


  var animals = new List<IAnimal>

  {

      new Cat(), new Dog(), new Cat()

  };


  foreach (var animal in animals)

  {

      switch (animal)

      {

          case Cat cat:

              Debug.WriteLine("This is a cat");

              break;

          case Dog dog:

              Debug.WriteLine("This is a dog");

              break;

      }

  }

这个输出看起来像:


这是一只猫


这是一只狗


这是一只猫


我没有展示它,但是cat和dog变量是非常好的、类型良好的对象引用,您可以在它们在范围内时使用它们。



查看完整回答
反对 回复 2021-11-28
  • 3 回答
  • 0 关注
  • 195 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信