2013-07-12 28 views
2

想象一下,我有一個包含兩個項目的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? 
     } 
    } 
} 

我的問題如果我們嘗試在沒有參考/知識的項目中獲取對象的類型,會發生什麼?

它會返回接口嗎?它可以? 它能以某種方式引用該類型嗎? 它會返回「對象」嗎? 或者它會完全做其他事情嗎?

回答

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的一個實例,那麼您可能需要重新考慮您的設計或使用情況。

+0

謝謝,這一切都有道理。我一直認爲一個項目中的方法是從該項目中運行的,並且只能訪問編譯時可用的類型。我描述的場景隨機發生在我身上,並且不停地竊聽我,足以發佈這個問題! – kaykayman

1

在項目2您所看到的代碼仍然打算從項目1運行,這就是你的通話,因此將能夠給你什麼該接口是類型正確的信息。

我的猜測是輸出將像Project1.ClassA一樣,你之前擁有的任何東西。但可以肯定的只是運行的代碼,看看你會得到

2

您將得到類型Project1.ClassA

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; 
     } 

現在你可以使用使用接口的類的實例沒有太多反射(活化劑是使用內部反射來創建一個實例)。