2013-03-14 51 views
5

如果類型是接口,爲什麼Type.GetProperty(string)不從基接口獲取屬性?例如,下面的代碼打印:爲什麼C#Type.GetProperty()對於接口的行爲與基類不同?

System.String X 
null 
System.String X 
System.String X 

這似乎是不一致的:

void Main() 
{ 
    Console.WriteLine(typeof(I1).GetProperty("X")); 
    Console.WriteLine(typeof(I2).GetProperty("X")); 
    Console.WriteLine(typeof(C1).GetProperty("X")); 
    Console.WriteLine(typeof(C2).GetProperty("X"));; 
} 

public interface I1 { string X { get; } } 

public interface I2 : I1 { } 

public class C1 { public string X { get { return "x"; } } } 

public class C2 : C1 { } 

編輯:支持科爾的回答運行的另一個方面是:

public class C : I2 { 
    // not allowed: the error is 
    // 'I2.X' in explicit interface declaration is not a member of interface 
    string I2.X { get; set; } 

    // allowed 
    string I1.X { get; set; } 
} 
+0

它與它是一個類或接口沒有任何關係。 X是私人的,另一個是公共的。 – 2013-03-14 20:38:55

+0

接口可以顯式實現('隱藏'實現類上的方法),而類上的公共屬性始終可見。如果您在C1上顯式實現I1,則會看到相同的行爲,而如果隱式實現它,GetProperty將會找到它。 – 2013-03-14 20:40:59

+1

@CoryNelson所有接口屬性都是公共的。還是你說I2明確實現了I1,因此I1方法是私有的?如果這是真的,那麼爲什麼你可以通過一個I2的實例訪問X而不用投射? – ChaseMedallion 2013-03-14 21:04:56

回答

6

請記住,類繼承與接口實現不同。

派生類及其基類具有is-a的關係。如果D : BDB。如果B有一個屬性,那麼D根據定義也將具有相同的屬性,因爲那是什麼關係意味着; D的「物質」在某種意義上被其與B的關係所改變。

提供的接口沒有實現,所以當你說ID : IB,你是不是真的說ID是在你的類做同樣的方式IB。這甚至意味着什麼? IDIB不是東西;他們是協議。沒有什麼可以改變的。相反,你的意思是「實現ID的類也必須提供IB的實現。」

ID派生自IB的事實不改變ID,因爲它沒有改變的實質。它只是意味着任何承諾履行ID規定的合同的類別也必須準備好遵守一組額外的要求。請記住,如果IB提供了一個屬性X,「ID有一個屬性X?」的正確答案是ID要求你也執行IB,其中確實有一個屬性X,但它本身並沒有一個屬性X

+0

你在說什麼是有道理的,但是你可以將它放在某種C#文檔或者類和接口如何在不同的環境下進行描述?您能否指出反射API中的其他行爲與此區別是一致的(除GetMethod的明顯並行外)。例如,GetInterfaces()對類和接口的作用相同。 – ChaseMedallion 2013-03-14 21:14:38

+2

@ChaseMedallion:正如你所看到的,你的問題是關於反射庫的行爲。沒有任何要求Reflection的規則與C#,VB或F#或任何其他託管語言的規則相同。 C#規範對於Reflection應該做什麼沒有什麼可說的;您應該查找的文檔是Reflection庫的文檔。 – 2013-03-14 21:31:53

+0

@ChaseMedallion:我認爲'GetProperty()'_also_對於類和接口的作用是等價的。它返回在類型上定義的屬性。在'ID:IB'''''''''''''''''''上,'''接口實現的語義意味着'X'沒有在'ID'上定義。至於文件,恐怕我不知道。我只是想根據我對繼承的語義的理解,而不是那些實現來解釋你所看到的行爲。 – 2013-03-14 21:40:25

相關問題