C# 访问修饰符、继承和外部程序集

C# 访问修饰符、继承和外部程序集,c#,C#,假设我在myFramework命名空间中有一个基类: using System; using System.Collections.Generic; using System.Text; namespace myFramework { public class baseClass { internal int m_value; internal int getValue() { return m_value;

假设我在myFramework命名空间中有一个基类:

using System;
using System.Collections.Generic;
using System.Text;

namespace myFramework
{
    public class baseClass
    {
        internal int m_value;

        internal int getValue() {
            return m_value;
        }

        internal void setValue(int value) {
            m_value = value;
        }

    }
}
在MyApplication命名空间中,我从中继承:

using System;
using System.Collections.Generic;
using System.Text;
using myFramework;

namespace MyApplication
{
    class InheritedClass: baseClass
    {
    }
}
在MyApplication命名空间中的表单中,我使用它:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using myFramework;

namespace MyApplication
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InheritedClass inheritedClass = new InheritedClass();

            inheritedClass.setValue(10);
            textBox1.Text = inheritedClass.m_value.ToString();
        }
    }
}
正如你们所看到的,我已经用内部修饰符声明了m_值,这样我就可以从表单中访问它

现在,如果我在一个单独的程序集中编译myFramework呢?内部不再工作了?那么,我可以使用任何修改器吗?我甚至不能做更少的工作。我必须使用公共服务吗

不存在一个访问修饰符,它允许拥有一个类(继承类)的对象(表单)访问所有他所拥有的类和父类的所有成员,除了内部没有考虑所有权,但该类在哪里被声明? 更新:当然,在现实世界中,我的基类对表单(或视图)有严格的语义,所以我决定是否应该这样做,我的问题不是我是否应该这样做,我的问题是,是否有可能或者我是否会被迫使用合同设计之类的东西,我觉得为这些基本需求添加另一个工具是愚蠢的。

表单并不“拥有”类,表单可以说是“拥有”该类的一个实例,但即使这样也不清楚;通常我们用“自己”来表示“对……负有最终责任”,在这种情况下,某个物体必须在某个时候被处理或以其他方式“清理”

表单与基类的内部工作完全无关。若窗体需要访问基类的成员,那个么它应该是公共的。或者,如果基类的成员应该是private、internal、protected或protectedinternal,那么表单就没有处理它的业务

如果您希望将不相关的类访问权授予故意非公共成员,则说明您的设计出了问题。

表单不“拥有”该类,可以说表单“拥有”该类的实例,但即使是这样也不清楚;通常我们用“自己”来表示“对……负有最终责任”,在这种情况下,某个物体必须在某个时候被处理或以其他方式“清理”

表单与基类的内部工作完全无关。若窗体需要访问基类的成员,那个么它应该是公共的。或者,如果基类的成员应该是private、internal、protected或protectedinternal,那么表单就没有处理它的业务


如果您希望将不相关的类访问权授予故意非公共成员,则说明您的设计出了问题。

这里的“所有权”没有任何意义,这些是完全不相关的类。充其量,你可以跳过这个圈套。

所有权在这里没有任何意义,它们是完全不相关的类。充其量,你可以跳过这一环。

根据所示的示例,公共财产将完全满足你的需要。但是,如果您想隐藏成员(并且您提前知道哪些程序集需要访问它),InternalsVisibleToAttribute将起作用


我在不想暴露属性的情况下使用它,但我需要访问它进行测试。在这种情况下,我清楚地知道,我只希望我的测试程序集能够访问该属性,并且我可以控制它的使用方式。

根据所示的示例,公共属性将完全满足您的需要。但是,如果您想隐藏成员(并且您提前知道哪些程序集需要访问它),InternalsVisibleToAttribute将起作用


我在不想暴露属性的情况下使用它,但我需要访问它进行测试。在这种情况下,,我清楚地知道,我只希望我的测试程序集能够访问该属性,并且我可以控制它的使用方式。

谢谢,这个属性很有趣,但是对于未来未知的客户端应该可以看到的框架,我看不出我可以如何使用它?也许有一种方法可以在运行时注册这样的客户端?可访问性是非常重要的编译时特性。使用反射来解决这个问题是一个相当丑陋的黑客行为。感谢这个属性很有趣,但是对于一个应该对未知的未来客户端可见的框架,我不知道如何使用它?也许有一种方法可以在运行时注册这样的客户端?可访问性是一种编译时功能。使用反射来解决这个问题是一个相当丑陋的技巧。在UML语义中,所有权是有一定意义的。至于“若表单需要访问基类的成员,那个么它应该是公共的。”不,正是因为我不希望非表单类型的类访问这个基类。再次强调,语法不应该模糊语义需求。并不是因为语言不允许表达真实世界的语义,它才是正确的。这只是过去的继承,缺乏进化。因此,如果我这样做的话,肯定是在我的基类显然与表单无关的情况下,如果这个基类将实现一些接口,我将创建一些仅用于表单的接口,我将用我自己的语义丰富这些接口。如果表单与基类有一些特殊的双向关系,如果在某些其他语言中使用
friend
关键字,那么我们最好使用InternalsVisibleTo属性,但遗憾的是,这也使表单所在的程序集的其余部分可以看到它们。如果基类实现了仅由表单使用的接口,那么您可以将该方法放在其中一个接口中。然而,从这个例子来看,表单并没有什么不同于任何其他使用基类的类。至于“若表单需要访问基类的成员,那个么它应该是公共的。”不,正是因为我不希望非表单类型的类访问这个基类。再次强调,语法不应该模糊语义需求。并不是因为一种语言不允许表达真实世界的语义,它才是正确的