简体   繁体   English

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

[英]internal protected property still accessible from a different assembly

I'm setting up some demo code for a beginner session on accessibility and I found that I am able to access an internal protected property from a derived class.我正在为初学者 session 设置一些关于可访问性的演示代码,我发现我能够从派生的 class 访问内部受保护的属性。 What am I missing?我错过了什么?

Assembly 1组装 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();
        }
    }
}

Assembly 2组装 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);
        }
    }
}

Notice in ExampleClass.Go I can set a value to Prop5.请注意,在 ExampleClass.Go 中,我可以为 Prop5 设置一个值。 Why?为什么? It's marked as internal protected but I can't set a value on Prop4 (marked as internal)它被标记为内部受保护,但我无法在 Prop4 上设置值(标记为内部)

internal protected means "internal to the assembly OR an inherited class". internal protected表示“程序集内部或继承的类”。 So yes, if you have a public class with an protected internal member, another class that inherits that type in a different assembly can still access it because of the protected modifier:所以是的,如果您有一个公共 class 和一个受保护的内部成员,另一个 class 在不同的程序集中继承该类型仍然可以访问它,因为受保护的修饰符:

protected internal受保护的内部

The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly.类型或成员可以被声明它的程序集中的任何代码访问,可以从另一个程序集中的派生 class 中访问。 Access from another assembly must take place within a class declaration that derives from the class in which the protected internal element is declared, and it must take place through an instance of the derived class type.来自另一个程序集的访问必须在 class 派生的 class 声明中进行,其中声明了受保护的内部元素,并且必须通过派生的 class 类型的实例进行。

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

This is a limitation of the C# language.这是 C# 语言的限制。 The CLR supports the "Internal AND Protected" notion. CLR 支持“内部与保护”概念。 There is evidence of this with the MethodAttributes.FamANDAssem enumeration if you were emitting your own IL.如果您发出自己的 IL,则MethodAttributes.FamANDAssem枚举可以证明这一点。 If you really wanted this feature, you could do some IL post processing with something like Mono.Cecil.如果你真的想要这个功能,你可以用 Mono.Cecil 之类的东西做一些 IL 后处理。 Why the C# language does not expose this is only a guess: little need for it.为什么 C# 语言不公开这只是一个猜测:几乎不需要它。

Because it's how internal protected is intended to work.因为这是internal protected的工作方式。 Access is given for either children in inheritance tree ( protected part) or for the same assembly ( internal part) - see Access Modifiers on MSDN .为 inheritance 树( protected的部分)或同一组件( internal部分)中的子项提供访问权限 - 请参阅MSDN 上的访问修饰符

And your ExampleClass is in the inheritance tree of BaseClass , which defines Prop5 .您的ExampleClass位于BaseClass的 inheritance 树中,它定义了Prop5 So the access is thanks to protected part.所以访问是由于protected的部分。

By combining the protected and internal keywords, a class member can be marked protected internal — only derived types or types within the same assembly can access that member.通过结合 protected 和 internal 关键字,可以将 class 成员标记为受保护的内部 - 只有同一程序集中的派生类型或类型才能访问该成员。

This MSDN article answers all your questions.这篇 MSDN 文章回答了您的所有问题。

It looks like protected internal means protected or internal .看起来 protected internal 意味着protected 或 internal

Basically, it doesn't seem to work like that.基本上,它似乎不像那样工作。

See - http://msdn.microsoft.com/en-us/library/ba0a1yw2(VS.80).aspx请参阅 - http://msdn.microsoft.com/en-us/library/ba0a1yw2(VS.80).aspx

protected internal acts as an OR - access is restricted to derived classes or to the current assembly. protected internal 充当 OR - 访问仅限于派生类或当前程序集。

The protected keyword is a member access modifier. protected 关键字是成员访问修饰符。 A protected member is accessible from within the class in which it is declared, and from within any class derived from the class that declared this member.受保护的成员可以从声明它的 class 中访问,也可以从从声明该成员的 class 派生的任何 class 中访问。

http://msdn.microsoft.com/en-us/library/bcd5672a(v=vs.71).aspx http://msdn.microsoft.com/en-us/library/bcd5672a(v=vs.71).aspx

By combining the protected and internal keywords, a class member can be marked protected internal — only derived types or types within the same assembly can access that member.通过结合 protected 和 internal 关键字,可以将 class 成员标记为受保护的内部 - 只有同一程序集中的派生类型或类型才能访问该成员。

http://msdn.microsoft.com/en-us/library/ms173121(v=vs.80).aspx http://msdn.microsoft.com/en-us/library/ms173121(v=vs.80).aspx

Protected means that it is shared only with descendant classes, only private means that it can't be accessed by anyone else. Protected意味着它只与后代类共享,只有private意味着它不能被其他任何人访问。

Edit: Hans comment makes your question a little more clear.编辑:汉斯评论让你的问题更清楚一点。 When you combine modifiers like that, they combine inclusively not exclusively.当您像这样组合修饰符时,它们会包含性地组合而不是排他性地组合。 It is accesse in all the ways internal or protected can be.它可以通过internalprotected的所有方式访问。

Late answer but I got caught with the same issue.迟到的答案,但我遇到了同样的问题。 Eventualy I came up with a partial solution.最终我想出了一个部分解决方案。

    internal Int MyInt
    {
        get;
        protected set;
    }

It is still visible within the assembly but at least only inherithing classes can actualy change it.它在程序集中仍然可见,但至少只有继承类才能真正改变它。 It is enough for what I wanted.这对我想要的已经足够了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM