【问题标题】:What is interface casting for in C#?什么是 C# 中的接口转换?
【发布时间】:2014-04-20 21:50:16
【问题描述】:

我确实了解在 C# 中编写接口的工作原理,例如此处所述: codeguru explanation

interface IIntelligence
   {
      bool intelligent_behavior();
   }

   class Human: IIntelligence
   {
      public Human()
      {
          //.............
      }

/// Interface method definition in the class that implements it
      public bool intelligent_behavior()
      {
         Console.WriteLine("........");
         return true
      }
   }

然而,我对以下接口转换过程感到困惑:

Human human = new Human();
// The human object is casted to the interface type
IIntelligence humanIQ = (IIntelligence)human;
humanIQ.intelligent_behavior();

让一个类(在这种情况下为 Human)实现一个接口,然后将其实例 human 转换回该接口是什么意思?问题不在于它是如何工作的,而在于为什么这样做。

【问题讨论】:

    标签: c# interface casting


    【解决方案1】:

    .net 提供两种接口实现方式隐式实现和显式实现。

    当您使用隐式实现时,它将成为类型接口本身的一部分,例如,如果您有这样的 IPerson 接口:

    public interface IPerson
    {
    string Name{get;}
    }
    

    然后你按如下方式实现它:

    public class Person:IPerson
    {
    public string Name{get; ....}
    }
    

    您可以像这样(隐式)访问它:

    aPerson.Name;
    

    但如果你像这样(明确地)实现它:

    public class Person:IPerson
    {
    string IPerson.Name{get; ....} // notice that there's no need to include access modifier.
    }
    

    那么只能使用IPerson接口访问:

    ((IPerson)aPerson).Name;
    

    更新:

    实际上,显式接口实现允许我们实现具有相同名称的成员的不同接口。(如this Tutorial所示)

    【讨论】:

      【解决方案2】:

      有时你可能不知道对象是什么,但你知道它实现了某个接口。

      【讨论】:

      • 可能会发生,我想你会做一个baseObject is IInterface 来检查。很好奇方法参数还没有输入到IInterface
      【解决方案3】:

      一个简短而流行的例子。我们可以实现这样的代码: 接口 IIntelligence { 字符串谈话(); }

         class Cat: ICreature
         {
            public string Talk()
            {
               Console.WriteLine("Meow!");
               return true
            }
         }
      
         class Dog: ICreature
         {
            public string Talk()
            {
               Console.WriteLine("Arf!");
               return true
            }
         }
      
         class Human: ICreature
         {
            public string Talk()
            {
               Console.WriteLine("Hello!");
               return true
            }
         }
      

      然后我们可以使用以下代码:

      ICreature() creatures = new ICreature(){new Human(), new Dog(), new Cat()};
      foreach(IIntelligence creature in creatures){
        Console.WriteLine(creature.Talk());
      }
      

      更多详细信息,请参阅 google 中的“面向对象编程中的多态性”。

      【讨论】:

        【解决方案4】:

        这是为了访问显式接口实现。

        有时你想隐藏一个类实现一个接口的事实。这是通过显式实现接口来完成的。

        public class MyClass : IInterface
        {
             string IInterface.TheMethod(){}
        }
        

        【讨论】:

          【解决方案5】:

          出于同样的原因,您将派生类转换回它的基类。

          【讨论】:

            【解决方案6】:

            考虑这种情况。我在您的示例中添加了一个方法。

            interface IIntelligence
            {
                bool intelligent_behavior();
            }
            
            class Human: IIntelligence
            {
                public Human() { }  
            
                /// Interface method definition in the class that implements it
                public bool IIntelligence.intelligent_behavior()
                {
                    Console.WriteLine("........");
                    return true;
                }    
            
                //Some other method definition
                public bool intelligent_behaviour()
                {
                    return false;
                }
            }
            

            您将转换为 IIntelligence 以获得您想要的方法实现。

            【讨论】:

              【解决方案7】:

              我发现在为主应用程序开发插件时,转换为接口很有用。我创建了三个项目。第一个项目“connectorInterface”仅包含一个类定义,即接口。接口代码:

              public interface IConnectorDataReader
              {
                int ColumnCount
                {
                  get;
                }
              
                bool readNextRecord();
              
                string this[int i]
                {
                  get;
                }
              
                void reset();
              }
              

              第二个项目“dataSource1”(主应用程序的插件)实现了 IConnectorDataReader 接口,实现接口的类还有一些额外的私有方法。使用插件“dataSource1”时的第三个项目“主应用程序”使用此代码从插件“dataSource1”读取数据:

                Assembly assembly = Assembly.LoadFile(path); // path to dll
                Type type = assembly.GetType("dataSource1.DataReader");
                object myInstance = Activator.CreateInstance(type);
              
                MethodInfo method = type.GetMethod("getConnectorDataReader");
                object data = method.Invoke(myInstance, null);
              
                IConnectorDataReader reader =(IConnectorDataReader)data;
              
                // method usage
                while (reader.readNextRecord() == true) ....
              

              在我的例子中,转换对于读取插件数据很有用。我不在乎插件是如何实现的,只要它实现了通用接口。我关心和使用的是读取数据的常用方法。我认为接口很有用,也可以回溯到接口。

              【讨论】:

                猜你喜欢
                • 2011-07-07
                • 2016-03-14
                • 2010-10-11
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2023-01-21
                • 2011-11-25
                • 1970-01-01
                相关资源
                最近更新 更多