为什么C#Type.GetProperty()对于接口的行为与对于基类的行为不同?

为什么C#Type.GetProperty()对于接口的行为与对于基类的行为不同?,c#,reflection,properties,C#,Reflection,Properties,如果类型是接口,为什么Type.GetProperty(string)不能从基本接口获取属性?例如,打印以下代码: 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.

如果类型是接口,为什么
Type.GetProperty(string)
不能从基本接口获取属性?例如,打印以下代码:

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

请记住,类继承与接口实现不同

派生类及其基类具有is-A关系。如果
D:B
,则
D
是a
B
。如果
B
有一个属性,那么
D
根据定义也会有相同的属性,因为这就是关系的含义;
D
的“实质”在某种意义上由于它与
B
的关系而改变

接口不提供实现,所以当你说
ID:IB
时,你并不是真的说
ID
是一个
IB
,就像你对类所做的那样。那意味着什么<代码>ID和
IB
不是东西;它们是协议。没有什么可以改变的。相反,您的意思是“实现
ID
的类还必须提供
IB
的实现”

ID
源于
IB
的事实不会改变
ID
,因为它没有改变的实质。这仅仅意味着任何承诺履行
ID
规定的合同的类别也必须准备好遵守一组额外的要求


记住这一点,如果
IB
提供了一个属性
X
,“ID是否有属性
X
?”的正确答案是否定的。
ID
要求您也实现
IB
,它确实有属性
X
,但是它本身没有属性
X

,它与它是一个类或接口无关。一个是私有的,另一个是公共的。接口可以显式实现(“隐藏”实现类上的方法),而类上的公共属性总是可见的。如果在C1上显式实现I1,您将看到相同的行为,而如果隐式实现,则GetProperty将找到它。@CoryNelson所有接口属性都是公共的。或者你是说I2显式地实现了I1,因此它的I1方法是私有的?如果这是真的,那么为什么你可以通过I2实例访问X而不使用强制转换呢?@DanBryant:但是,如果你在C1上显式实现I1,你将无法调用新的C1().X。但是,如果在C1上非显式地实现I2,并且有一个变量I2 I2=new C1(),则可以调用I2.X。这表明这不是I2显式实现I1的问题,但我可能错了。@ChaseMedallion您是对的。暂时的疯狂。你说的很有道理,但你能用某种C#文档或描述类和接口在幕后的区别吗?您能否指出反射API中与此区别一致的其他行为(除了GetMethod的明显并行性)。例如,GetInterfaces()相当于类和接口。@ChaseMedallion:正如您所注意到的,您的问题是关于反射库的行为。不要求反射规则与C#、VB、F#或任何其他托管语言的规则相同。C#规范没有说明反射应该做什么;您应该查找的文档是反射库的文档。@ChaseMedallion:我认为
GetProperty()
同样适用于类和接口。它返回在类型上定义的属性。在
ID:IB
上带有
X
IB
中,接口实现的语义意味着
X
未在
ID
上定义。至于文件,恐怕我不知道。我只是想根据我对继承语义的理解,而不是对实现语义的理解,来解释您看到的行为。