8

如this question中所述,我希望属性具有内部getter和受保护的setter的问题,我认为我通过执行以下操作解决了这个问题:

public class Accessor : AccessorBase
{
    private Connection _connection;

    protected void setConnection(Connection value)
    {
        _connection = value;
    }

    internal Connection GetConnection()
    {
        return _connection;
    }
    ...
}

但是,我现在收到此错误:

可访问性不一致:参数类型“连接”比方法“setConnection(连接)”更难访问

这是因为我有internal class Connection. 我宁愿不创建Connection一个公共类,虽然Accessor 需要是公共的,那么如何在仍然保持内部 getter 和受保护的 setter 的同时解决这个错误?

4

7 回答 7

10

不幸的是,C# 不支持“内部受保护”访问修饰符(仅支持“内部受保护”),这意味着任何protected成员在程序集之外都是可见的,并且不能使用内部类型。
使用internal代替protected将是最合乎逻辑的解决方案。

您可以在 Microsoft Connect 上投票,以便有朝一日将其添加到 C# 中。

更新:从 C# 7.2 开始,您可以使用private protected它。

于 2010-01-07T19:14:49.010 回答
5

创建一个IConnection您的内部Connection对象实现的公共接口。让您的GetConnectionandSetConnection方法接受并返回IConnection而不是Connection.

基本的SOLID原则再次获胜。

于 2010-01-07T19:26:16.337 回答
2

...任何受保护的成员在程序集之外都是可见的,并且不能使用内部类型。

-- Pent Ploompuu 的回答

解决此问题的一种方法是Connection公开,同时将其所有实例方法和构造函数设为内部。

于 2010-01-07T19:32:03.687 回答
1

如果类 Connection 是内部的,则派生 Accessor 的类将无法调用受保护的 setConnection,因为它无权访问 Connection。

如果要保护 setConnection,则 Connection 必须是公共的。

于 2010-01-07T19:14:09.447 回答
0

抱歉,如果您需要确切的设置,您需要Connection公开您的课程。

于 2010-01-07T19:17:20.017 回答
0

不幸的是,你不能那样做。由于Connection是内部的,因此从另一个程序集的 Accessor 派生的某些类将无法看到Connection,即使您将 setter 标记为protected internal它不会解决任何问题。

你唯一的希望是让课程 Connection 公开。

于 2010-01-07T19:23:05.780 回答
0

Coincoin 是正确的,Accessor是任何人都可以从中派生的公共类,这也意味着来自不同的程序集。该派生类现在具有受保护的方法,您需要将内部(来自另一个程序集)类传递给该方法。这永远行不通。

您需要进行Accessor内部或Connection公开,或者最好遵循Randolphos 的回答

这是问题的代码示例

组装 1

//this class is only visible in Assembly 1
internal class Connection
{

}
public class Accessor
{
   protected void SetConnection(Connection con) { }
}

装配 2 - 参考装配 1

//possible because Accessor is public
DerivedAccessor : Accessor
{
   void SomeMethod()
    {
        this.SetConnection(????) // you can't pass Connection, its not visible to Assembly2 
    }
}
于 2010-01-07T19:28:43.837 回答