C# 来自外部项目的参考接口

C# 来自外部项目的参考接口,c#,interface,projects-and-solutions,C#,Interface,Projects And Solutions,假设我有一个包含两个项目的VisualStudio解决方案。在此场景中,项目1知道项目2,但项目2不知道项目1 项目1 using Project2; namespace Project1 { public class ClassA : IMyInterface {} public class Main { public void MainMethod() { ARandomClass aRandomClass = new AR

假设我有一个包含两个项目的VisualStudio解决方案。在此场景中,项目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?
      }
   }
}
我的问题是,如果我们试图在一个没有引用/知识的项目中获取对象的类型,会发生什么

它会返回接口吗?可以吗? 它是否能够引用该类型? 它会返回“object”吗?
或者它会完全执行其他操作吗?

它将返回实际的类型
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中的信息:

但您不能这样做,因为Project2在编译时不了解Project1:


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

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


我猜输出将类似于Project1.ClassA,包含之前的任何内容。但要确定的是,只需运行该代码并查看您得到的输出,您将得到Project1.ClassA类型

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正在使用内部反射来创建实例)。

谢谢,这一切都是有意义的。我一直认为一个项目中的方法是从该项目中运行的,它们只能访问编译时可用的类型。我描述的场景是随机出现的,一直困扰着我,以至于我发布了这个问题!
public void MyMethod() {
         Type type = MyItem.GetType(); // what happens here?
      }
   public IMyInterface MyMethod()
        {
            Type type = MyItem.GetType(); // what happens here?
            IMyInterface value = (IMyInterface)Activator.CreateInstance(type);
            return value;
        }