来自外部项目的参考界面

时间:2013-07-12 11:11:09

标签: c# interface projects-and-solutions

想象一下,我有一个包含两个项目的visual studio解决方案。在这种情况下,项目1知道项目2,但项目2不知道项目1。

项目1

using Project2;

namespace Project1
{
   public class ClassA : IMyInterface {}

   public class Main {

       public void MainMethod()
       {
           ARandomClass aRandomClass = new ARandomClass();
           IMyInterface classA = new ClassA();
           aRandomClass.MyItem = classA;
           aRandomClass.MyMethod();
       }

   }
}

项目2

namespace Project2
{
   public interface IMyInterface { }

   public class ARandomClass {
      public IMyInterface MyItem { get; set; }

      public void MyMethod() {
         Type type = MyItem.GetType(); // what happens here?
      }
   }
}

我的问题是,如果我们试图获得一个没有该类型的参考/知识的项目中的对象类型会发生什么?

它会返回界面吗?它可以? 它能以某种方式引用该类型吗? 它会返回“对象”吗? 或者它会完全做其他事情吗?

4 个答案:

答案 0 :(得分:3)

它将返回实际类型ClassA

所有类型信息都可通过反射检查和检查。您无法在编译时直接引用该类型。

项目2 仍然可以在ClassA上呼叫成员,这只会很困难/繁琐,因为您只能使用反射或dynamic

public void MyMethod() {
    Type type = MyItem.GetType(); //gets a `System.Type` representing `ClassA'
    Console.WriteLine(type.FullName);//outputs "Project1.ClassA"
}

只是展示你能做什么或不能做什么,说ClassA被定义为:

public class ClassA : IMyInterface 
{
    public string MyField = "Hello world!";
}

你将无法做到这一点:

public void MyMethod() {
    Console.WriteLine(MyItem.MyField); //compiler error
}

可以这样做,因为Project2可以在运行时从Project1 访问信息:

public void MyMethod() {
    //lookup the field via reflection
    Type type = MyItem.GetType();
    Console.WriteLine(type.GetField("MyField").GetValue(MyItem));

    //simpler way than above using dynamic, but still at runtime
    dynamic dynamicItem = MyItem;
    Console.WriteLine(MyItem.MyField);
}

无法执行此操作,因为Project2在编译时不了解Project1

public void MyMethod() {
    //cast to type ClassA
    ClassA classAMyItem = (ClassA)MyItem; //compile error
    Console.WriteLine(classAMyItem.MyField); //compile error
}

这基本上是多态性的租户之一。您的MyMethod不应该知道,也不应该关心 MyItem超出IMyInterface的范围。它通常只关心访问IMyInterface中定义的属性,方法和事件。如果 关心它是ClassA的实例,那么您可能需要重新考虑您的设计或用法。

答案 1 :(得分:2)

您将获得类型为Project1.ClassA

答案 2 :(得分:1)

您在项目2中看到的代码仍将从项目1运行,这是您的调用所在,因此能够为您提供有关Interface类型的正确信息。

我的猜测是输出将像Project1.ClassA一样,无论你有什么。但是要确保只运行该代码并查看您获得的输出

答案 3 :(得分:0)

public void MyMethod() {
         Type type = MyItem.GetType(); // what happens here?
      }

类型变量将指向您的AClass。您可以将代码更改为如下所示:

   public IMyInterface MyMethod()
        {
            Type type = MyItem.GetType(); // what happens here?
            IMyInterface value = (IMyInterface)Activator.CreateInstance(type);
            return value;
        }

现在你可以使用接口使用接口而不需要太多的反射(Activator在内部使用反射来创建实例)。