2

想象一下,我有一个包含两个项目的视觉工作室解决方案。在这种情况下,项目 1 知道项目 2,但项目 2 不知道项目 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

4 回答 4

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不应该知道,也不应该关心除了. 它通常应该只关心访问定义在. 如果它确实关心它是 的一个实例,那么您可能需要重新考虑您的设计或使用。MyItemIMyInterfaceIMyInterfaceClassA

于 2013-07-12T11:18:51.850 回答
2

您将获得类型为 Project1.ClassA

于 2013-07-12T11:25:39.570 回答
1

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

我的猜测是输出将类似于 Project1.ClassA 与您之前拥有的任何内容。但要确保只需运行该代码并查看您得到的输出

于 2013-07-12T11:22:31.120 回答
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 在内部使用反射来创建实例)。

于 2013-07-12T11:39:13.943 回答