C# 接口(interface)对象列表 - 类型转换单个元素

标签 c# list methods interface casting

我有一个 C# 问题,过去几天一直困扰着我。我将尝试根据我正在做的事情的抽象描述来解释它。希望它很容易理解。 ;)

假设我们有一个接口(interface)

interface iFoo {
   void a();
}

此外,我还有 2 个实现此接口(interface)的类及其中的方法:

class bar1 : iFoo
{
   public void a() { Console.WriteLine("bar1"); }
   public void anotherMethodBar1() { Console.Write("I love "); }
}

class bar2 : iFoo
{
   public void a() { Console.WriteLine("bar2"); }
   public void anotherMethodBar2() { Console.Write("beer"); }
}

每个类还提供了一个额外的独特方法 - anotherMethodBar1() 和 anotherMethodBar2()。现在在我的 main() 中,我想创建一个列表,其中包含实现我的接口(interface)的对象,如下所示:

namespace ExampleFooBar
{
    class Program
    {
        static void Main(string[] args)
        {
            List<iFoo> fooBarObjects = new List<iFoo>();
            fooBarObjects.Add(new bar1());
            fooBarObjects.Add(new bar2());

            for(int i = 0; i < fooBarObjects.Count; i++)
            {
                if(fooBarObjects[i].GetType() == typeof(bar1))
                {
                    //Cast element to bar1 and use anotherMethodBar1()
                }
                if(fooBarObjects[i].GetType() == typeof(bar2))
                {
                    //Cast element to bar2 and use anotherMethodBar2()
                }
            }
        }
    }
}

如您所见,我想调用每个对象自己的(不包含在接口(interface)中)方法(基于类,我们有 anotherMethodBar1() 或 anotherMethodBar2(),它们不是接口(interface)的一部分)。问题是——我该怎么做?我是 C# 的新手,到目前为止我的经验与转换没什么关系,但现在我需要它。这甚至是通过使用类型转换来完成的还是有其他方法?无法简单地调用方法

if(fooBarObjects[i].GetType() == typeof(bar1))
{
    fooBarObjects[i].anotherMethodBar1();
}

因为 C# 不理解底层的确切类型,因此该对象的可用方法/函数只是标准一次加上我的 a() 方法:

  • a()
  • 等于()
  • 获取类型()
  • GetHashCode()
  • ToString()

我真的试图找到一个解决方案,但到目前为止,只有相反的问题经常被问到——对象列表到接口(interface)列表的转换。

非常感谢和最诚挚的问候!

最佳答案

        for(int i = 0; i < fooBarObjects.Count; i++)
        {
            if(fooBarObjects[i] is bar1)
            {
                ((bar1)fooBarObjects[i]).anotherMethodBar1();
            }
            else if (fooBarObjects[i] is bar2)
            {
                ((bar2)fooBarObjects[i]).anotherMethodBar2();
            }
        }

关键是关键字 is,它检查对象是否属于 bar1 类型(或从 bar1 派生的任何类型)和 (type)object 将对象转换为指定类型的语法。

另一种选择是使用 as 关键字进行强制转换,如果无法完成强制转换则返回 null

        for(int i = 0; i < fooBarObjects.Count; i++)
        {
            var b1 = fooBarObjects[i] as bar1;
            if  (b1 != null)
            {
                b1.anotherMethodBar1();
            }
            else
            {
                var b2 = fooBarObjects[i] as bar2;
                if (b2 != null)
                {
                    b2.anotherMethodBar2();
                }
            }
        }

第二个选项被认为优于第一个选项,因为运行时只需进行一次类型检查(在 as 关键字中)而不是两次(is())。

关于C# 接口(interface)对象列表 - 类型转换单个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17063739/

相关文章:

c# - 如何将 Observable Collection 的 Item 属性绑定(bind)到 Switch 状态?

python - 如何从数据框中的两列创建列表字典

python - 将方法作为函数参数传递

methods - "Method [show] does not exist"是什么意思?

c# - 在不注册服务类型的情况下解析 autofac 中的服务

c# - 将 C# 日期时间转换为字符串并返回

c# - 如何在 C# 中修复 future 日期的 ArgumentOutOfRangeException

python - 在python中迭代未知数量的嵌套循环

c++ - 在 C++ 中将字符串和列表添加到映射

c++ - 是否允许 C++ 编译器/链接器删除未使用的方法?