仍可从不同的程序集访问内部受保护的属性

Dus*_*vis 15 .net c#

我正在为可访问性的初学者会话设置一些演示代码,我发现我能够从派生类访问内部受保护的属性.我错过了什么?

大会1

namespace Accessibility
{
    class Program
    {
        static void Main(string[] args)
        {
            ExampleClass c = new ExampleClass();
            c.Go();
            //c.Prop1 = 10;
        }
    }

    class ExampleClass : DerivedClass
    {
        public void Go()
        {
            this.Prop1 = 10;
            this.Prop2 = 10;
            //this.Prop3 = 10; //Doesn't work
            //this.Prop4 = 10; //Doesn't work
            this.Prop5 = 10; //why does this work?!

            this.DoSomething();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

大会2

namespace Accessibility.Models
{
    public class BaseClass
    {
        public int Prop1 { get; set; }
        protected int Prop2 { get; set; }
        private int Prop3 { get; set; }

        internal int Prop4 { get; set; }
        internal protected int Prop5 { get; set; }
        //internal public int Prop6 { get; set; } //Invalid 
        //internal private int Prop7 { get; set; } //Invalid

        public BaseClass()
        {
            this.Prop3 = 27;
        }
    }

    public class DerivedClass : BaseClass
    {
        public void DoSomething()
        {
            this.Prop1 = 10;
            this.Prop2 = 10;
            //this.Prop3 = 10; //Doesn't work
            this.Prop4 = 10;
            this.Prop5 = 10;

            PropertyInfo Prop3pi = typeof(DerivedClass).GetProperty("Prop3", BindingFlags.Instance | BindingFlags.NonPublic);
            int value = (int)Prop3pi.GetValue(this, null);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意在ExampleClass.Go我可以设置一个值为Prop5.为什么?它被标记为内部受保护但我无法在Prop4上设置值(标记为内部)

vcs*_*nes 20

internal protected表示"程序集内部或继承的类".所以,是的,如果你有一个带有受保护内部成员的公共类,另一个在不同程序集中继承该类型的类仍然可以访问它,因为受保护的修饰符:

保护内部

类型或构件可以通过在声明它,该组件的任何代码被访问从另一个组件中的导出类中.来自另一个程序集的访问必须在一个类声明中进行,该类声明派生自声明受保护的内部元素的类,并且它必须通过派生类类型的实例进行.

参考:http://msdn.microsoft.com/en-us/library/ms173121.aspx

这是C#语言的限制.CLR支持"内部和受保护"概念.MethodAttributes.FamANDAssem如果您发射自己的IL ,则有枚举的证据.如果你真的 想要这个功能,你可以使用Mono.Cecil之类的东西做一些IL后期处理.为什么C#语言没有暴露这个只是一个猜测:几乎不需要它.


NOt*_*Dev 6

因为它是如何internal protected工作的.在继承树(protected部分)或同一程序集(internal部分)中为子项提供访问权限 - 请参阅MSDN上的访问修饰符.

而你的ExampleClass是继承树BaseClass,它定义了Prop5.所以访问protected部分归功于此.